@codeyam/codeyam-cli 0.1.7 → 0.1.9

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 (576) hide show
  1. package/analyzer-template/.build-info.json +8 -8
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/package.json +9 -9
  4. package/analyzer-template/packages/ai/package.json +1 -1
  5. package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +34 -3
  6. package/analyzer-template/packages/ai/src/lib/completionCall.ts +14 -2
  7. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +27 -0
  8. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/coercePrimitivesToArraysBySchema.ts +62 -0
  9. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +78 -2
  10. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +0 -33
  11. package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +19 -7
  12. package/analyzer-template/packages/analyze/src/lib/asts/index.ts +7 -2
  13. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +9 -1
  14. package/analyzer-template/packages/analyze/src/lib/files/analyze/dependencyResolver.ts +0 -6
  15. package/analyzer-template/packages/analyze/src/lib/files/analyze/findOrCreateEntity.ts +12 -0
  16. package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +65 -28
  17. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +83 -0
  18. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +0 -98
  19. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +23 -4
  20. package/analyzer-template/packages/aws/package.json +2 -2
  21. package/analyzer-template/packages/database/index.ts +1 -0
  22. package/analyzer-template/packages/database/package.json +3 -3
  23. package/analyzer-template/packages/database/src/lib/kysely/db.ts +8 -0
  24. package/analyzer-template/packages/database/src/lib/kysely/tables/editorScenariosTable.ts +93 -0
  25. package/analyzer-template/packages/database/src/lib/loadCommits.ts +31 -20
  26. package/analyzer-template/packages/database/src/lib/loadEntities.ts +0 -6
  27. package/analyzer-template/packages/database/src/lib/loadReadyToBeCapturedAnalyses.ts +0 -5
  28. package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +94 -143
  29. package/analyzer-template/packages/database/src/lib/updateFreshAnalysisStatus.ts +58 -42
  30. package/analyzer-template/packages/database/src/lib/updateFreshAnalysisStatusWithScenarios.ts +81 -65
  31. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.ts +29 -1
  32. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.ts +33 -5
  33. package/analyzer-template/packages/github/dist/database/index.d.ts +1 -0
  34. package/analyzer-template/packages/github/dist/database/index.d.ts.map +1 -1
  35. package/analyzer-template/packages/github/dist/database/index.js +1 -0
  36. package/analyzer-template/packages/github/dist/database/index.js.map +1 -1
  37. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -0
  38. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
  39. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +5 -0
  40. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
  41. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts +25 -0
  42. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts.map +1 -0
  43. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js +76 -0
  44. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -0
  45. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts +5 -0
  46. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts.map +1 -1
  47. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts.map +1 -1
  48. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js +23 -13
  49. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js.map +1 -1
  50. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts.map +1 -1
  51. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js +0 -6
  52. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js.map +1 -1
  53. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.d.ts.map +1 -1
  54. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js +1 -4
  55. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
  56. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
  57. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +76 -90
  58. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js.map +1 -1
  59. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatus.d.ts.map +1 -1
  60. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatus.js +41 -30
  61. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatus.js.map +1 -1
  62. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatusWithScenarios.d.ts.map +1 -1
  63. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatusWithScenarios.js +68 -57
  64. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatusWithScenarios.js.map +1 -1
  65. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.d.ts.map +1 -1
  66. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js +29 -1
  67. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js.map +1 -1
  68. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.d.ts.map +1 -1
  69. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +33 -5
  70. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
  71. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.d.ts +2 -0
  72. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.d.ts.map +1 -1
  73. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.js +2 -0
  74. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.js.map +1 -1
  75. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts +1 -0
  76. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  77. package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts +10 -0
  78. package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts.map +1 -1
  79. package/analyzer-template/packages/github/package.json +1 -1
  80. package/analyzer-template/packages/types/src/enums/ProjectFramework.ts +2 -0
  81. package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +1 -0
  82. package/analyzer-template/packages/types/src/types/Scenario.ts +10 -0
  83. package/analyzer-template/packages/ui-components/package.json +1 -1
  84. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.d.ts +2 -0
  85. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.d.ts.map +1 -1
  86. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.js +2 -0
  87. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.js.map +1 -1
  88. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts +1 -0
  89. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  90. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts +10 -0
  91. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts.map +1 -1
  92. package/analyzer-template/playwright/captureFromUrl.ts +89 -82
  93. package/analyzer-template/project/constructMockCode.ts +136 -43
  94. package/analyzer-template/project/reconcileMockDataKeys.ts +19 -14
  95. package/analyzer-template/project/start.ts +3 -0
  96. package/analyzer-template/project/startScenarioCapture.ts +9 -0
  97. package/analyzer-template/project/writeClientLogRoute.ts +125 -0
  98. package/analyzer-template/project/writeMockDataTsx.ts +17 -0
  99. package/analyzer-template/project/writeScenarioComponents.ts +36 -7
  100. package/analyzer-template/tsconfig.json +13 -1
  101. package/background/src/lib/virtualized/project/constructMockCode.js +115 -34
  102. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  103. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +17 -11
  104. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
  105. package/background/src/lib/virtualized/project/start.js +2 -0
  106. package/background/src/lib/virtualized/project/start.js.map +1 -1
  107. package/background/src/lib/virtualized/project/startScenarioCapture.js +5 -0
  108. package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
  109. package/background/src/lib/virtualized/project/writeClientLogRoute.js +110 -0
  110. package/background/src/lib/virtualized/project/writeClientLogRoute.js.map +1 -0
  111. package/background/src/lib/virtualized/project/writeMockDataTsx.js +12 -0
  112. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  113. package/background/src/lib/virtualized/project/writeScenarioComponents.js +29 -7
  114. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  115. package/codeyam-cli/scripts/apply-setup.js +208 -11
  116. package/codeyam-cli/scripts/apply-setup.js.map +1 -1
  117. package/codeyam-cli/src/__tests__/memory-scripts/filter-session.test.js +196 -0
  118. package/codeyam-cli/src/__tests__/memory-scripts/filter-session.test.js.map +1 -0
  119. package/codeyam-cli/src/__tests__/memory-scripts/read-json-field.test.js +114 -0
  120. package/codeyam-cli/src/__tests__/memory-scripts/read-json-field.test.js.map +1 -0
  121. package/codeyam-cli/src/__tests__/memory-scripts/ripgrep-fallback.test.js +149 -0
  122. package/codeyam-cli/src/__tests__/memory-scripts/ripgrep-fallback.test.js.map +1 -0
  123. package/codeyam-cli/src/cli.js +2 -0
  124. package/codeyam-cli/src/cli.js.map +1 -1
  125. package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js +45 -0
  126. package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js.map +1 -0
  127. package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js +101 -47
  128. package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js.map +1 -1
  129. package/codeyam-cli/src/commands/analyze.js +17 -7
  130. package/codeyam-cli/src/commands/analyze.js.map +1 -1
  131. package/codeyam-cli/src/commands/default.js +14 -2
  132. package/codeyam-cli/src/commands/default.js.map +1 -1
  133. package/codeyam-cli/src/commands/editor.js +3215 -0
  134. package/codeyam-cli/src/commands/editor.js.map +1 -0
  135. package/codeyam-cli/src/commands/init.js +107 -45
  136. package/codeyam-cli/src/commands/init.js.map +1 -1
  137. package/codeyam-cli/src/data/techStacks.js +77 -0
  138. package/codeyam-cli/src/data/techStacks.js.map +1 -0
  139. package/codeyam-cli/src/utils/__tests__/analyzerFinalization.test.js +144 -0
  140. package/codeyam-cli/src/utils/__tests__/analyzerFinalization.test.js.map +1 -0
  141. package/codeyam-cli/src/utils/__tests__/backgroundServer.test.js +46 -0
  142. package/codeyam-cli/src/utils/__tests__/backgroundServer.test.js.map +1 -0
  143. package/codeyam-cli/src/utils/__tests__/devServerState.test.js +134 -0
  144. package/codeyam-cli/src/utils/__tests__/devServerState.test.js.map +1 -0
  145. package/codeyam-cli/src/utils/__tests__/editorApi.test.js +127 -0
  146. package/codeyam-cli/src/utils/__tests__/editorApi.test.js.map +1 -0
  147. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +855 -0
  148. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -0
  149. package/codeyam-cli/src/utils/__tests__/editorCapture.test.js +93 -0
  150. package/codeyam-cli/src/utils/__tests__/editorCapture.test.js.map +1 -0
  151. package/codeyam-cli/src/utils/__tests__/editorDevServer.test.js +304 -0
  152. package/codeyam-cli/src/utils/__tests__/editorDevServer.test.js.map +1 -0
  153. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js +121 -0
  154. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js.map +1 -0
  155. package/codeyam-cli/src/utils/__tests__/editorImageVerifier.test.js +294 -0
  156. package/codeyam-cli/src/utils/__tests__/editorImageVerifier.test.js.map +1 -0
  157. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js +542 -0
  158. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js.map +1 -0
  159. package/codeyam-cli/src/utils/__tests__/editorLoaderHelpers.test.js +520 -0
  160. package/codeyam-cli/src/utils/__tests__/editorLoaderHelpers.test.js.map +1 -0
  161. package/codeyam-cli/src/utils/__tests__/editorMockState.test.js +270 -0
  162. package/codeyam-cli/src/utils/__tests__/editorMockState.test.js.map +1 -0
  163. package/codeyam-cli/src/utils/__tests__/editorPreloadHelpers.test.js +217 -0
  164. package/codeyam-cli/src/utils/__tests__/editorPreloadHelpers.test.js.map +1 -0
  165. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js +339 -0
  166. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js.map +1 -0
  167. package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js +153 -0
  168. package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js.map +1 -0
  169. package/codeyam-cli/src/utils/__tests__/editorScenarioLookup.test.js +139 -0
  170. package/codeyam-cli/src/utils/__tests__/editorScenarioLookup.test.js.map +1 -0
  171. package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js +221 -0
  172. package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js.map +1 -0
  173. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js +855 -0
  174. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -0
  175. package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js +213 -0
  176. package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js.map +1 -0
  177. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js +1742 -0
  178. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js.map +1 -0
  179. package/codeyam-cli/src/utils/__tests__/git.editor.test.js +134 -0
  180. package/codeyam-cli/src/utils/__tests__/git.editor.test.js.map +1 -0
  181. package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js +107 -0
  182. package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js.map +1 -0
  183. package/codeyam-cli/src/utils/__tests__/parseRegisterArg.test.js +101 -0
  184. package/codeyam-cli/src/utils/__tests__/parseRegisterArg.test.js.map +1 -0
  185. package/codeyam-cli/src/utils/__tests__/pathIgnoring.test.js +9 -0
  186. package/codeyam-cli/src/utils/__tests__/pathIgnoring.test.js.map +1 -1
  187. package/codeyam-cli/src/utils/__tests__/project.test.js +65 -0
  188. package/codeyam-cli/src/utils/__tests__/project.test.js.map +1 -0
  189. package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js +227 -0
  190. package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js.map +1 -0
  191. package/codeyam-cli/src/utils/__tests__/scenarioMarkers.test.js +121 -0
  192. package/codeyam-cli/src/utils/__tests__/scenarioMarkers.test.js.map +1 -0
  193. package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js +300 -0
  194. package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js.map +1 -0
  195. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +50 -4
  196. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  197. package/codeyam-cli/src/utils/__tests__/templateConsistency.test.js +51 -0
  198. package/codeyam-cli/src/utils/__tests__/templateConsistency.test.js.map +1 -0
  199. package/codeyam-cli/src/utils/__tests__/webappDetection.test.js +142 -0
  200. package/codeyam-cli/src/utils/__tests__/webappDetection.test.js.map +1 -0
  201. package/codeyam-cli/src/utils/analyzer.js +9 -0
  202. package/codeyam-cli/src/utils/analyzer.js.map +1 -1
  203. package/codeyam-cli/src/utils/analyzerFinalization.js +96 -0
  204. package/codeyam-cli/src/utils/analyzerFinalization.js.map +1 -0
  205. package/codeyam-cli/src/utils/backgroundServer.js +104 -12
  206. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  207. package/codeyam-cli/src/utils/buildFlags.js +4 -0
  208. package/codeyam-cli/src/utils/buildFlags.js.map +1 -0
  209. package/codeyam-cli/src/utils/database.js +37 -2
  210. package/codeyam-cli/src/utils/database.js.map +1 -1
  211. package/codeyam-cli/src/utils/devModeEvents.js +40 -0
  212. package/codeyam-cli/src/utils/devModeEvents.js.map +1 -0
  213. package/codeyam-cli/src/utils/devServerState.js +71 -0
  214. package/codeyam-cli/src/utils/devServerState.js.map +1 -0
  215. package/codeyam-cli/src/utils/editorApi.js +73 -0
  216. package/codeyam-cli/src/utils/editorApi.js.map +1 -0
  217. package/codeyam-cli/src/utils/editorAudit.js +176 -0
  218. package/codeyam-cli/src/utils/editorAudit.js.map +1 -0
  219. package/codeyam-cli/src/utils/editorCapture.js +102 -0
  220. package/codeyam-cli/src/utils/editorCapture.js.map +1 -0
  221. package/codeyam-cli/src/utils/editorDevServer.js +197 -0
  222. package/codeyam-cli/src/utils/editorDevServer.js.map +1 -0
  223. package/codeyam-cli/src/utils/editorEntityChangeStatus.js +44 -0
  224. package/codeyam-cli/src/utils/editorEntityChangeStatus.js.map +1 -0
  225. package/codeyam-cli/src/utils/editorImageVerifier.js +155 -0
  226. package/codeyam-cli/src/utils/editorImageVerifier.js.map +1 -0
  227. package/codeyam-cli/src/utils/editorJournal.js +225 -0
  228. package/codeyam-cli/src/utils/editorJournal.js.map +1 -0
  229. package/codeyam-cli/src/utils/editorLoaderHelpers.js +113 -0
  230. package/codeyam-cli/src/utils/editorLoaderHelpers.js.map +1 -0
  231. package/codeyam-cli/src/utils/editorMockState.js +248 -0
  232. package/codeyam-cli/src/utils/editorMockState.js.map +1 -0
  233. package/codeyam-cli/src/utils/editorPreloadHelpers.js +135 -0
  234. package/codeyam-cli/src/utils/editorPreloadHelpers.js.map +1 -0
  235. package/codeyam-cli/src/utils/editorPreview.js +132 -0
  236. package/codeyam-cli/src/utils/editorPreview.js.map +1 -0
  237. package/codeyam-cli/src/utils/editorScenarioSwitch.js +112 -0
  238. package/codeyam-cli/src/utils/editorScenarioSwitch.js.map +1 -0
  239. package/codeyam-cli/src/utils/editorScenarios.js +332 -0
  240. package/codeyam-cli/src/utils/editorScenarios.js.map +1 -0
  241. package/codeyam-cli/src/utils/editorSeedAdapter.js +173 -0
  242. package/codeyam-cli/src/utils/editorSeedAdapter.js.map +1 -0
  243. package/codeyam-cli/src/utils/entityChangeStatus.js +349 -0
  244. package/codeyam-cli/src/utils/entityChangeStatus.js.map +1 -0
  245. package/codeyam-cli/src/utils/entityChangeStatus.server.js +158 -0
  246. package/codeyam-cli/src/utils/entityChangeStatus.server.js.map +1 -0
  247. package/codeyam-cli/src/utils/fileMetadata.js +5 -0
  248. package/codeyam-cli/src/utils/fileMetadata.js.map +1 -1
  249. package/codeyam-cli/src/utils/fileWatcher.js +25 -9
  250. package/codeyam-cli/src/utils/fileWatcher.js.map +1 -1
  251. package/codeyam-cli/src/utils/git.js +103 -0
  252. package/codeyam-cli/src/utils/git.js.map +1 -1
  253. package/codeyam-cli/src/utils/install-skills.js +55 -13
  254. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  255. package/codeyam-cli/src/utils/interactiveSyncWatcher.js +126 -0
  256. package/codeyam-cli/src/utils/interactiveSyncWatcher.js.map +1 -0
  257. package/codeyam-cli/src/utils/parseRegisterArg.js +31 -0
  258. package/codeyam-cli/src/utils/parseRegisterArg.js.map +1 -0
  259. package/codeyam-cli/src/utils/pathIgnoring.js +19 -7
  260. package/codeyam-cli/src/utils/pathIgnoring.js.map +1 -1
  261. package/codeyam-cli/src/utils/project.js +15 -5
  262. package/codeyam-cli/src/utils/project.js.map +1 -1
  263. package/codeyam-cli/src/utils/queue/__tests__/heartbeat.test.js +11 -11
  264. package/codeyam-cli/src/utils/queue/__tests__/heartbeat.test.js.map +1 -1
  265. package/codeyam-cli/src/utils/queue/__tests__/manager.test.js +22 -0
  266. package/codeyam-cli/src/utils/queue/__tests__/manager.test.js.map +1 -1
  267. package/codeyam-cli/src/utils/queue/heartbeat.js +13 -5
  268. package/codeyam-cli/src/utils/queue/heartbeat.js.map +1 -1
  269. package/codeyam-cli/src/utils/queue/job.js +70 -1
  270. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  271. package/codeyam-cli/src/utils/queue/manager.js +7 -6
  272. package/codeyam-cli/src/utils/queue/manager.js.map +1 -1
  273. package/codeyam-cli/src/utils/scenarioCoverage.js +75 -0
  274. package/codeyam-cli/src/utils/scenarioCoverage.js.map +1 -0
  275. package/codeyam-cli/src/utils/scenarioMarkers.js +134 -0
  276. package/codeyam-cli/src/utils/scenarioMarkers.js.map +1 -0
  277. package/codeyam-cli/src/utils/scenariosManifest.js +159 -0
  278. package/codeyam-cli/src/utils/scenariosManifest.js.map +1 -0
  279. package/codeyam-cli/src/utils/serverState.js +57 -2
  280. package/codeyam-cli/src/utils/serverState.js.map +1 -1
  281. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +82 -11
  282. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  283. package/codeyam-cli/src/utils/simulationGateMiddleware.js +8 -1
  284. package/codeyam-cli/src/utils/simulationGateMiddleware.js.map +1 -1
  285. package/codeyam-cli/src/utils/slugUtils.js +25 -0
  286. package/codeyam-cli/src/utils/slugUtils.js.map +1 -0
  287. package/codeyam-cli/src/utils/syncMocksMiddleware.js +2 -2
  288. package/codeyam-cli/src/utils/syncMocksMiddleware.js.map +1 -1
  289. package/codeyam-cli/src/utils/testRunner.js +158 -0
  290. package/codeyam-cli/src/utils/testRunner.js.map +1 -0
  291. package/codeyam-cli/src/utils/webappDetection.js +35 -2
  292. package/codeyam-cli/src/utils/webappDetection.js.map +1 -1
  293. package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js +40 -0
  294. package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js.map +1 -0
  295. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js +567 -0
  296. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js.map +1 -0
  297. package/codeyam-cli/src/webserver/app/lib/clientErrors.js +65 -0
  298. package/codeyam-cli/src/webserver/app/lib/clientErrors.js.map +1 -0
  299. package/codeyam-cli/src/webserver/app/lib/database.js +41 -27
  300. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  301. package/codeyam-cli/src/webserver/app/lib/dbNotifier.js.map +1 -1
  302. package/codeyam-cli/src/webserver/app/lib/git.js +397 -0
  303. package/codeyam-cli/src/webserver/app/lib/git.js.map +1 -0
  304. package/codeyam-cli/src/webserver/backgroundServer.js +108 -18
  305. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  306. package/codeyam-cli/src/webserver/build/client/assets/{CopyButton-CtmbP4Gl.js → CopyButton-BPXZwM4t.js} +1 -1
  307. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-DlMph_Hm.js → EntityItem-BcgbViKV.js} +3 -3
  308. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-B-0PjGOU.js → EntityTypeBadge-g3saevPb.js} +1 -1
  309. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-DN9eiJAO.js → EntityTypeIcon-CQIG2qda.js} +9 -9
  310. package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-Bu6c6aDe.js +1 -0
  311. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-rE_fI2h2.js → InteractivePreview-DYFW3lDD.js} +3 -3
  312. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-CnatsCw2.js → LibraryFunctionPreview-DLeucoVX.js} +1 -1
  313. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-CSP6DZrh.js → LoadingDots-BU_OAEMP.js} +1 -1
  314. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-CMK8Q7yk.js → LogViewer-ceAyBX-H.js} +1 -1
  315. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-TCV_HBjy.js → ReportIssueModal-BzHcG7SE.js} +3 -3
  316. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-CG2uh31y.js → SafeScreenshot-BED4B6sP.js} +1 -1
  317. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-CU_TDYd8.js → ScenarioViewer-Bd-hxofb.js} +3 -3
  318. package/codeyam-cli/src/webserver/build/client/assets/Spinner-Bb5uFQ5V.js +34 -0
  319. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-D7IoaWUW.js → TruncatedFilePath-C8OKAR5x.js} +1 -1
  320. package/codeyam-cli/src/webserver/build/client/assets/ViewportInspectBar-oAf2Kqsf.js +1 -0
  321. package/codeyam-cli/src/webserver/build/client/assets/{_index-B8z7mjR-.js → _index-DLxKhri3.js} +3 -3
  322. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-DZu78RI1.js → activity.(_tab)-BcY3q6nt.js} +6 -6
  323. package/codeyam-cli/src/webserver/build/client/assets/addon-canvas-DpzMmAy5.js +1 -0
  324. package/codeyam-cli/src/webserver/build/client/assets/addon-fit-YJmn1quW.js +12 -0
  325. package/codeyam-cli/src/webserver/build/client/assets/addon-web-links-Duc5hnl7.js +1 -0
  326. package/codeyam-cli/src/webserver/build/client/assets/addon-webgl-DI8QOUvO.js +58 -0
  327. package/codeyam-cli/src/webserver/build/client/assets/{agent-transcripts-Dm5RS9il.js → agent-transcripts-Bni3iiUj.js} +5 -5
  328. package/codeyam-cli/src/webserver/build/client/assets/api.dev-mode-events-l0sNRNKZ.js +1 -0
  329. package/codeyam-cli/src/webserver/build/client/assets/api.editor-audit-l0sNRNKZ.js +1 -0
  330. package/codeyam-cli/src/webserver/build/client/assets/api.editor-capture-scenario-l0sNRNKZ.js +1 -0
  331. package/codeyam-cli/src/webserver/build/client/assets/api.editor-client-errors-l0sNRNKZ.js +1 -0
  332. package/codeyam-cli/src/webserver/build/client/assets/api.editor-commit-l0sNRNKZ.js +1 -0
  333. package/codeyam-cli/src/webserver/build/client/assets/api.editor-dev-server-l0sNRNKZ.js +1 -0
  334. package/codeyam-cli/src/webserver/build/client/assets/api.editor-entity-status-l0sNRNKZ.js +1 -0
  335. package/codeyam-cli/src/webserver/build/client/assets/api.editor-file-diff-l0sNRNKZ.js +1 -0
  336. package/codeyam-cli/src/webserver/build/client/assets/api.editor-file-l0sNRNKZ.js +1 -0
  337. package/codeyam-cli/src/webserver/build/client/assets/api.editor-journal-entry-l0sNRNKZ.js +1 -0
  338. package/codeyam-cli/src/webserver/build/client/assets/api.editor-journal-image._-l0sNRNKZ.js +1 -0
  339. package/codeyam-cli/src/webserver/build/client/assets/api.editor-journal-l0sNRNKZ.js +1 -0
  340. package/codeyam-cli/src/webserver/build/client/assets/api.editor-journal-screenshot-l0sNRNKZ.js +1 -0
  341. package/codeyam-cli/src/webserver/build/client/assets/api.editor-journal-update-l0sNRNKZ.js +1 -0
  342. package/codeyam-cli/src/webserver/build/client/assets/api.editor-load-commit-l0sNRNKZ.js +1 -0
  343. package/codeyam-cli/src/webserver/build/client/assets/api.editor-project-info-l0sNRNKZ.js +1 -0
  344. package/codeyam-cli/src/webserver/build/client/assets/api.editor-refresh-l0sNRNKZ.js +1 -0
  345. package/codeyam-cli/src/webserver/build/client/assets/api.editor-register-scenario-l0sNRNKZ.js +1 -0
  346. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-coverage-l0sNRNKZ.js +1 -0
  347. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-data-l0sNRNKZ.js +1 -0
  348. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-image._-l0sNRNKZ.js +1 -0
  349. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenarios-l0sNRNKZ.js +1 -0
  350. package/codeyam-cli/src/webserver/build/client/assets/api.editor-switch-scenario-l0sNRNKZ.js +1 -0
  351. package/codeyam-cli/src/webserver/build/client/assets/api.editor-test-results-l0sNRNKZ.js +1 -0
  352. package/codeyam-cli/src/webserver/build/client/assets/{book-open-Bp5FLkd4.js → book-open-BYOypzCa.js} +2 -2
  353. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-DQJA9f4o.js → chevron-down-C_Pmso5S.js} +2 -2
  354. package/codeyam-cli/src/webserver/build/client/assets/{chunk-JZWAC4HX-7VptmeIr.js → chunk-JZWAC4HX-C4pqxYJB.js} +1 -1
  355. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-B6C4LY9o.js → circle-check-BVMi9VA5.js} +2 -2
  356. package/codeyam-cli/src/webserver/build/client/assets/{copy-6nzYCu0G.js → copy-n2FB0_Sw.js} +3 -3
  357. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CC6AbExI.js +41 -0
  358. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BsDh6TSF.js +1 -0
  359. package/codeyam-cli/src/webserver/build/client/assets/editor-PBc_6L9R.js +10 -0
  360. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-4FzHlcNn.js +41 -0
  361. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-C6PQhwY5.js → entity._sha._-BsDXNp45.js} +9 -9
  362. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-BgAqUtTZ.js +6 -0
  363. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-Bmshgrij.js +6 -0
  364. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-p9hhkjJM.js +6 -0
  365. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-C7ysA4Jq.js → entity._sha_.edit._scenarioId-BMvVHNXU.js} +2 -2
  366. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-CU6EUArK.js → entry.client-DTvKq3TY.js} +1 -1
  367. package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-EWpfFU4X.js → fileTableUtils-cPo8LiG3.js} +1 -1
  368. package/codeyam-cli/src/webserver/build/client/assets/{files-CrxAoWIL.js → files-BZrlFE1F.js} +1 -1
  369. package/codeyam-cli/src/webserver/build/client/assets/git-DdZcvjGh.js +1 -0
  370. package/codeyam-cli/src/webserver/build/client/assets/globals-B8vTTNy2.css +1 -0
  371. package/codeyam-cli/src/webserver/build/client/assets/{index-7-1FmlHo.js → index-10oVnAAH.js} +1 -1
  372. package/codeyam-cli/src/webserver/build/client/assets/{index-DuYcwYp_.js → index-BcvgDzbZ.js} +1 -1
  373. package/codeyam-cli/src/webserver/build/client/assets/index-yHOVb4rc.js +15 -0
  374. package/codeyam-cli/src/webserver/build/client/assets/{labs-CPPVOSWB.js → labs-Zk7ryIM1.js} +1 -1
  375. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-BnDcD54R.js → loader-circle-DaAZ_H2w.js} +2 -2
  376. package/codeyam-cli/src/webserver/build/client/assets/manifest-65850841.js +1 -0
  377. package/codeyam-cli/src/webserver/build/client/assets/memory-9gnxSZlb.js +101 -0
  378. package/codeyam-cli/src/webserver/build/client/assets/{pause-DhQX2g22.js → pause-f5-1lKBt.js} +3 -3
  379. package/codeyam-cli/src/webserver/build/client/assets/root-BwX8YgFb.js +67 -0
  380. package/codeyam-cli/src/webserver/build/client/assets/{search-DborVoKD.js → search-Di64LWVb.js} +2 -2
  381. package/codeyam-cli/src/webserver/build/client/assets/{settings-BWunYSXt.js → settings-0OrEMU6J.js} +1 -1
  382. package/codeyam-cli/src/webserver/build/client/assets/{simulations-BtrtCYJg.js → simulations-DWT-CvLy.js} +1 -1
  383. package/codeyam-cli/src/webserver/build/client/assets/{terminal-Bs4NC-VZ.js → terminal-Br7MOqts.js} +3 -3
  384. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-DTf3Jojp.js → triangle-alert-BLdiCuG-.js} +2 -2
  385. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-BE43Hjti.js +1 -0
  386. package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-C14nCb1q.js +2 -0
  387. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-BsQb6rFd.js → useReportContext-O-jkvSPx.js} +1 -1
  388. package/codeyam-cli/src/webserver/build/client/assets/{useToast-BOur3mUv.js → useToast-9FIWuYfK.js} +1 -1
  389. package/codeyam-cli/src/webserver/build/client/assets/xterm-BqvuqXEL.js +27 -0
  390. package/codeyam-cli/src/webserver/build/server/assets/index-DEEQf4pi.js +1 -0
  391. package/codeyam-cli/src/webserver/build/server/assets/init-CkWmyFY2.js +10 -0
  392. package/codeyam-cli/src/webserver/build/server/assets/server-build-BHi-9O8W.js +439 -0
  393. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  394. package/codeyam-cli/src/webserver/build-info.json +5 -5
  395. package/codeyam-cli/src/webserver/devServer.js +39 -5
  396. package/codeyam-cli/src/webserver/devServer.js.map +1 -1
  397. package/codeyam-cli/src/webserver/editorProxy.js +877 -0
  398. package/codeyam-cli/src/webserver/editorProxy.js.map +1 -0
  399. package/codeyam-cli/src/webserver/scripts/codeyam-preload.mjs +414 -0
  400. package/codeyam-cli/src/webserver/scripts/journalCapture.ts +230 -0
  401. package/codeyam-cli/src/webserver/server.js +258 -1
  402. package/codeyam-cli/src/webserver/server.js.map +1 -1
  403. package/codeyam-cli/src/webserver/terminalServer.js +726 -0
  404. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -0
  405. package/codeyam-cli/templates/chrome-extension-react/EXTENSION_SETUP.md +75 -0
  406. package/codeyam-cli/templates/chrome-extension-react/README.md +46 -0
  407. package/codeyam-cli/templates/chrome-extension-react/gitignore +15 -0
  408. package/codeyam-cli/templates/chrome-extension-react/index.html +12 -0
  409. package/codeyam-cli/templates/chrome-extension-react/package.json +27 -0
  410. package/codeyam-cli/templates/chrome-extension-react/popup.html +12 -0
  411. package/codeyam-cli/templates/chrome-extension-react/public/manifest.json +15 -0
  412. package/codeyam-cli/templates/chrome-extension-react/src/background/service-worker.ts +7 -0
  413. package/codeyam-cli/templates/chrome-extension-react/src/globals.css +6 -0
  414. package/codeyam-cli/templates/chrome-extension-react/src/lib/storage.ts +37 -0
  415. package/codeyam-cli/templates/chrome-extension-react/src/popup/App.tsx +12 -0
  416. package/codeyam-cli/templates/chrome-extension-react/src/popup/main.tsx +10 -0
  417. package/codeyam-cli/templates/chrome-extension-react/tsconfig.json +24 -0
  418. package/codeyam-cli/templates/chrome-extension-react/vite.config.ts +41 -0
  419. package/codeyam-cli/templates/codeyam-editor-claude.md +147 -0
  420. package/codeyam-cli/templates/editor-step-hook.py +236 -0
  421. package/codeyam-cli/templates/expo-react-native/MOBILE_SETUP.md +89 -0
  422. package/codeyam-cli/templates/expo-react-native/README.md +41 -0
  423. package/codeyam-cli/templates/expo-react-native/app/(tabs)/_layout.tsx +33 -0
  424. package/codeyam-cli/templates/expo-react-native/app/(tabs)/index.tsx +12 -0
  425. package/codeyam-cli/templates/expo-react-native/app/(tabs)/settings.tsx +12 -0
  426. package/codeyam-cli/templates/expo-react-native/app/_layout.tsx +12 -0
  427. package/codeyam-cli/templates/expo-react-native/app.json +18 -0
  428. package/codeyam-cli/templates/expo-react-native/babel.config.js +9 -0
  429. package/codeyam-cli/templates/expo-react-native/gitignore +12 -0
  430. package/codeyam-cli/templates/expo-react-native/global.css +3 -0
  431. package/codeyam-cli/templates/expo-react-native/lib/storage.ts +32 -0
  432. package/codeyam-cli/templates/expo-react-native/metro.config.js +6 -0
  433. package/codeyam-cli/templates/expo-react-native/nativewind-env.d.ts +1 -0
  434. package/codeyam-cli/templates/expo-react-native/package.json +38 -0
  435. package/codeyam-cli/templates/expo-react-native/tailwind.config.js +10 -0
  436. package/codeyam-cli/templates/expo-react-native/tsconfig.json +10 -0
  437. package/codeyam-cli/templates/isolation-route/next-app.tsx.template +80 -0
  438. package/codeyam-cli/templates/isolation-route/next-pages.tsx.template +79 -0
  439. package/codeyam-cli/templates/isolation-route/vite-react.tsx.template +78 -0
  440. package/codeyam-cli/templates/msw/browser-setup.ts.template +47 -0
  441. package/codeyam-cli/templates/msw/handler-router.ts.template +47 -0
  442. package/codeyam-cli/templates/msw/server-setup.ts.template +52 -0
  443. package/codeyam-cli/templates/nextjs-prisma-sqlite/AUTH_PATTERNS.md +308 -0
  444. package/codeyam-cli/templates/nextjs-prisma-sqlite/AUTH_UPGRADE.md +304 -0
  445. package/codeyam-cli/templates/nextjs-prisma-sqlite/DATABASE.md +126 -0
  446. package/codeyam-cli/templates/nextjs-prisma-sqlite/FEATURE_PATTERNS.md +37 -0
  447. package/codeyam-cli/templates/nextjs-prisma-sqlite/README.md +53 -0
  448. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/api/todos/route.ts +17 -0
  449. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/codeyam-isolate/layout.tsx +12 -0
  450. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/globals.css +26 -0
  451. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/layout.tsx +34 -0
  452. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/lib/prisma.ts +24 -0
  453. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/page.tsx +10 -0
  454. package/codeyam-cli/templates/nextjs-prisma-sqlite/env +4 -0
  455. package/codeyam-cli/templates/nextjs-prisma-sqlite/eslint.config.mjs +11 -0
  456. package/codeyam-cli/templates/nextjs-prisma-sqlite/gitignore +64 -0
  457. package/codeyam-cli/templates/nextjs-prisma-sqlite/next.config.ts +14 -0
  458. package/codeyam-cli/templates/nextjs-prisma-sqlite/package.json +39 -0
  459. package/codeyam-cli/templates/nextjs-prisma-sqlite/postcss.config.mjs +7 -0
  460. package/codeyam-cli/templates/nextjs-prisma-sqlite/prisma/schema.prisma +27 -0
  461. package/codeyam-cli/templates/nextjs-prisma-sqlite/prisma/seed.ts +40 -0
  462. package/codeyam-cli/templates/nextjs-prisma-sqlite/prisma.config.ts +12 -0
  463. package/codeyam-cli/templates/nextjs-prisma-sqlite/seed-adapter.ts +92 -0
  464. package/codeyam-cli/templates/nextjs-prisma-sqlite/tsconfig.json +34 -0
  465. package/codeyam-cli/templates/nextjs-prisma-sqlite/vitest.config.ts +13 -0
  466. package/codeyam-cli/templates/nextjs-prisma-supabase/README.md +52 -0
  467. package/codeyam-cli/templates/nextjs-prisma-supabase/SUPABASE_SETUP.md +104 -0
  468. package/codeyam-cli/templates/nextjs-prisma-supabase/app/api/todos/route.ts +17 -0
  469. package/codeyam-cli/templates/nextjs-prisma-supabase/app/globals.css +26 -0
  470. package/codeyam-cli/templates/nextjs-prisma-supabase/app/layout.tsx +34 -0
  471. package/codeyam-cli/templates/nextjs-prisma-supabase/app/lib/prisma.ts +20 -0
  472. package/codeyam-cli/templates/nextjs-prisma-supabase/app/lib/supabase.ts +12 -0
  473. package/codeyam-cli/templates/nextjs-prisma-supabase/app/page.tsx +10 -0
  474. package/codeyam-cli/templates/nextjs-prisma-supabase/env +9 -0
  475. package/codeyam-cli/templates/nextjs-prisma-supabase/eslint.config.mjs +11 -0
  476. package/codeyam-cli/templates/nextjs-prisma-supabase/gitignore +40 -0
  477. package/codeyam-cli/templates/nextjs-prisma-supabase/next.config.ts +11 -0
  478. package/codeyam-cli/templates/nextjs-prisma-supabase/package.json +37 -0
  479. package/codeyam-cli/templates/nextjs-prisma-supabase/postcss.config.mjs +7 -0
  480. package/codeyam-cli/templates/nextjs-prisma-supabase/prisma/schema.prisma +27 -0
  481. package/codeyam-cli/templates/nextjs-prisma-supabase/prisma/seed.ts +39 -0
  482. package/codeyam-cli/templates/nextjs-prisma-supabase/prisma.config.ts +12 -0
  483. package/codeyam-cli/templates/nextjs-prisma-supabase/tsconfig.json +34 -0
  484. package/codeyam-cli/templates/skills/codeyam-dev-mode/SKILL.md +237 -0
  485. package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +148 -0
  486. package/codeyam-cli/templates/{codeyam-memory.md → skills/codeyam-memory/SKILL.md} +215 -0
  487. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/deprecated-prompt.md +100 -0
  488. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/detect-deprecated-patterns.mjs +139 -0
  489. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/find-exports.mjs +52 -0
  490. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/misleading-api-prompt.md +117 -0
  491. package/codeyam-cli/templates/skills/codeyam-memory/scripts/lib/read-json-field.mjs +61 -0
  492. package/codeyam-cli/templates/skills/codeyam-memory/scripts/lib/ripgrep-fallback.mjs +155 -0
  493. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/analyze-prompt.md +46 -0
  494. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/cleanup.mjs +13 -0
  495. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/filter-session.mjs +95 -0
  496. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/preprocess.mjs +160 -0
  497. package/package.json +17 -10
  498. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +22 -4
  499. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
  500. package/packages/ai/src/lib/completionCall.js +10 -2
  501. package/packages/ai/src/lib/completionCall.js.map +1 -1
  502. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +21 -0
  503. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  504. package/packages/ai/src/lib/dataStructure/helpers/coercePrimitivesToArraysBySchema.js +54 -0
  505. package/packages/ai/src/lib/dataStructure/helpers/coercePrimitivesToArraysBySchema.js.map +1 -0
  506. package/packages/ai/src/lib/dataStructure/helpers/stripNullableMarkers.js +34 -0
  507. package/packages/ai/src/lib/dataStructure/helpers/stripNullableMarkers.js.map +1 -0
  508. package/packages/ai/src/lib/generateEntityScenarioData.js +57 -2
  509. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  510. package/packages/ai/src/lib/generateExecutionFlows.js +0 -11
  511. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
  512. package/packages/analyze/src/lib/ProjectAnalyzer.js +13 -4
  513. package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
  514. package/packages/analyze/src/lib/asts/index.js +4 -2
  515. package/packages/analyze/src/lib/asts/index.js.map +1 -1
  516. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +8 -1
  517. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  518. package/packages/analyze/src/lib/files/analyze/dependencyResolver.js +0 -5
  519. package/packages/analyze/src/lib/files/analyze/dependencyResolver.js.map +1 -1
  520. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js +9 -0
  521. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js.map +1 -1
  522. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +54 -27
  523. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -1
  524. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +65 -0
  525. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  526. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +0 -40
  527. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -1
  528. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +18 -4
  529. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  530. package/packages/database/index.js +1 -0
  531. package/packages/database/index.js.map +1 -1
  532. package/packages/database/src/lib/kysely/db.js +5 -0
  533. package/packages/database/src/lib/kysely/db.js.map +1 -1
  534. package/packages/database/src/lib/kysely/tables/editorScenariosTable.js +76 -0
  535. package/packages/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -0
  536. package/packages/database/src/lib/loadCommits.js +23 -13
  537. package/packages/database/src/lib/loadCommits.js.map +1 -1
  538. package/packages/database/src/lib/loadEntities.js +0 -6
  539. package/packages/database/src/lib/loadEntities.js.map +1 -1
  540. package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js +1 -4
  541. package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
  542. package/packages/database/src/lib/updateCommitMetadata.js +76 -90
  543. package/packages/database/src/lib/updateCommitMetadata.js.map +1 -1
  544. package/packages/database/src/lib/updateFreshAnalysisStatus.js +41 -30
  545. package/packages/database/src/lib/updateFreshAnalysisStatus.js.map +1 -1
  546. package/packages/database/src/lib/updateFreshAnalysisStatusWithScenarios.js +68 -57
  547. package/packages/database/src/lib/updateFreshAnalysisStatusWithScenarios.js.map +1 -1
  548. package/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js +29 -1
  549. package/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js.map +1 -1
  550. package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +33 -5
  551. package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
  552. package/packages/types/src/enums/ProjectFramework.js +2 -0
  553. package/packages/types/src/enums/ProjectFramework.js.map +1 -1
  554. package/scripts/npm-post-install.cjs +34 -0
  555. package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-C1rIyZdV.js +0 -34
  556. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-D-QUFOwe.js +0 -21
  557. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DmzSmblj.js +0 -1
  558. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-DVTcUnur.js +0 -6
  559. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-BVgNO76F.js +0 -6
  560. package/codeyam-cli/src/webserver/build/client/assets/git-BldHtKeW.js +0 -15
  561. package/codeyam-cli/src/webserver/build/client/assets/globals-CLmFdUae.css +0 -1
  562. package/codeyam-cli/src/webserver/build/client/assets/manifest-717e346a.js +0 -1
  563. package/codeyam-cli/src/webserver/build/client/assets/memory-0wMU4KXe.js +0 -93
  564. package/codeyam-cli/src/webserver/build/client/assets/root-DqfSDjyQ.js +0 -62
  565. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-D_bDZyDU.js +0 -1
  566. package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-DZp6rrQD.js +0 -2
  567. package/codeyam-cli/src/webserver/build/server/assets/index-B8jmgmn2.js +0 -1
  568. package/codeyam-cli/src/webserver/build/server/assets/server-build-9OU4lmvL.js +0 -285
  569. package/scripts/finalize-analyzer.cjs +0 -13
  570. /package/codeyam-cli/templates/{codeyam-diagnose.md → commands/codeyam-diagnose.md} +0 -0
  571. /package/codeyam-cli/templates/{codeyam-debug.md → skills/codeyam-debug/SKILL.md} +0 -0
  572. /package/codeyam-cli/templates/{codeyam-new-rule.md → skills/codeyam-new-rule/SKILL.md} +0 -0
  573. /package/codeyam-cli/templates/{codeyam-setup.md → skills/codeyam-setup/SKILL.md} +0 -0
  574. /package/codeyam-cli/templates/{codeyam-sim.md → skills/codeyam-sim/SKILL.md} +0 -0
  575. /package/codeyam-cli/templates/{codeyam-test.md → skills/codeyam-test/SKILL.md} +0 -0
  576. /package/codeyam-cli/templates/{codeyam-verify.md → skills/codeyam-verify/SKILL.md} +0 -0
@@ -0,0 +1,877 @@
1
+ import http from 'http';
2
+ import net from 'net';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { getProjectRoot } from "../state.js";
6
+ import { createMockStateManager, } from "../utils/editorMockState.js";
7
+ import { computeEditorPorts } from "../utils/editorDevServer.js";
8
+ /**
9
+ * Normalize a target URL by stripping trailing slashes for consistency.
10
+ *
11
+ * Previously this also replaced `localhost` with `127.0.0.1`, but that broke
12
+ * forwarding to dev servers that bind to IPv6 only (e.g. Vite 6 on macOS
13
+ * binds to `[::1]`). The hostname is now left as-is — `resolveLoopbackAddress`
14
+ * probes the actual target at startup to pick the right address.
15
+ */
16
+ export function normalizeTargetUrl(url) {
17
+ try {
18
+ const parsed = new URL(url);
19
+ return parsed.toString().replace(/\/$/, '');
20
+ }
21
+ catch {
22
+ return url;
23
+ }
24
+ }
25
+ /**
26
+ * Probe a localhost port to determine the correct loopback address.
27
+ * Dev servers may bind to IPv4 (127.0.0.1), IPv6 (::1), or both.
28
+ * Returns the first address that accepts a TCP connection.
29
+ */
30
+ export async function resolveLoopbackAddress(port) {
31
+ const candidates = ['127.0.0.1', '::1'];
32
+ for (const host of candidates) {
33
+ try {
34
+ const connected = await new Promise((resolve) => {
35
+ const socket = new net.Socket();
36
+ socket.setTimeout(1000);
37
+ socket.once('connect', () => {
38
+ socket.destroy();
39
+ resolve(true);
40
+ });
41
+ socket.once('error', () => {
42
+ socket.destroy();
43
+ resolve(false);
44
+ });
45
+ socket.once('timeout', () => {
46
+ socket.destroy();
47
+ resolve(false);
48
+ });
49
+ socket.connect(port, host);
50
+ });
51
+ if (connected) {
52
+ return host;
53
+ }
54
+ }
55
+ catch {
56
+ // Try next candidate
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+ // Global key so the proxy survives HMR
62
+ const GLOBAL_KEY = '__codeyam_editor_proxy__';
63
+ // ─── Live Preview Health ─────────────────────────────────────────────
64
+ const PREVIEW_HEALTH_KEY = '__codeyam_preview_health__';
65
+ function getPreviewHealth() {
66
+ return globalThis[PREVIEW_HEALTH_KEY] ?? null;
67
+ }
68
+ function setPreviewHealth(report) {
69
+ globalThis[PREVIEW_HEALTH_KEY] = report;
70
+ }
71
+ /**
72
+ * Get the current live preview health report (read by API endpoint).
73
+ */
74
+ export function getPreviewHealthReport() {
75
+ return getPreviewHealth();
76
+ }
77
+ /**
78
+ * Reset preview health state (called when a new HTML page is served).
79
+ */
80
+ export function resetPreviewHealth() {
81
+ setPreviewHealth(null);
82
+ }
83
+ /**
84
+ * Error-catching script injected into HTML responses.
85
+ * Uses vanilla JS for maximum compatibility.
86
+ */
87
+ export const PREVIEW_HEALTH_SCRIPT = `<script data-codeyam-health>
88
+ (function() {
89
+ var errors = [];
90
+ var reported = false;
91
+ function report(type, msg, stack) {
92
+ errors.push({ type: type, message: msg, stack: stack, timestamp: Date.now() });
93
+ if (!reported) {
94
+ reported = true;
95
+ setTimeout(function() { flush(); }, 500);
96
+ }
97
+ }
98
+ function flush() {
99
+ fetch('/__codeyam__/preview-health', {
100
+ method: 'POST',
101
+ headers: { 'Content-Type': 'application/json' },
102
+ body: JSON.stringify({ errors: errors, url: location.href })
103
+ }).catch(function(){});
104
+ reported = false;
105
+ errors = [];
106
+ }
107
+ window.addEventListener('error', function(e) {
108
+ report('error', e.message, e.error && e.error.stack);
109
+ });
110
+ window.addEventListener('unhandledrejection', function(e) {
111
+ report('unhandledrejection', String(e.reason), e.reason && e.reason.stack);
112
+ });
113
+ var origError = console.error;
114
+ console.error = function() {
115
+ report('console.error', Array.prototype.join.call(arguments, ' '));
116
+ origError.apply(console, arguments);
117
+ };
118
+ window.addEventListener('load', function() {
119
+ setTimeout(function() {
120
+ var hasContent = document.body && document.body.innerText.trim().length > 0;
121
+ fetch('/__codeyam__/preview-health', {
122
+ method: 'POST',
123
+ headers: { 'Content-Type': 'application/json' },
124
+ body: JSON.stringify({
125
+ loaded: true,
126
+ hasContent: hasContent,
127
+ url: location.href,
128
+ errorCount: errors.length
129
+ })
130
+ }).catch(function(){});
131
+ }, 1000);
132
+ });
133
+ })();
134
+ </script>`;
135
+ const CACHE_TTL_MS = 500;
136
+ let scenarioCache = { data: null, timestamp: 0 };
137
+ // Session config extracted from the active scenario — drives cookie injection
138
+ let sessionConfig = undefined;
139
+ // localStorage config extracted from the active scenario — drives HTML injection
140
+ let localStorageConfig = null;
141
+ // Active scenario ID — used to gate localStorage seeding (only re-seed on switch)
142
+ let activeScenarioId = null;
143
+ // Prototype ID — used to gate a one-time localStorage.clear() when a new project is scaffolded
144
+ let currentPrototypeId = null;
145
+ // Max body size to buffer for mock matching (10MB)
146
+ const MAX_BODY_SIZE = 10 * 1024 * 1024;
147
+ function getProxyState() {
148
+ return globalThis[GLOBAL_KEY] ?? null;
149
+ }
150
+ function setProxyState(state) {
151
+ globalThis[GLOBAL_KEY] = state;
152
+ }
153
+ /**
154
+ * Get or create the mock state manager (survives HMR via globalThis).
155
+ */
156
+ function getMockStateManager() {
157
+ const key = '__codeyam_mock_state__';
158
+ if (!globalThis[key]) {
159
+ globalThis[key] = createMockStateManager();
160
+ }
161
+ return globalThis[key];
162
+ }
163
+ /**
164
+ * Get the proxy URL if the proxy is running.
165
+ */
166
+ export function getProxyUrl() {
167
+ const state = getProxyState();
168
+ if (!state)
169
+ return null;
170
+ return `http://localhost:${state.port}`;
171
+ }
172
+ /**
173
+ * Read the active scenario's mock data from disk, with brief caching.
174
+ * Feeds the data into the MockStateManager.
175
+ *
176
+ * For application/user scenarios (type-aware): only loads `externalApis`
177
+ * into the mock state manager. All DB-backed routes flow through to the
178
+ * real app (database is seeded with real data).
179
+ *
180
+ * For component scenarios (or legacy): loads all routes as before.
181
+ */
182
+ function readScenarioData() {
183
+ const now = Date.now();
184
+ if (scenarioCache.data !== null &&
185
+ now - scenarioCache.timestamp < CACHE_TTL_MS) {
186
+ return scenarioCache.data;
187
+ }
188
+ const projectRoot = getProjectRoot() || process.env.CODEYAM_ROOT_PATH || process.cwd();
189
+ const activeScenarioPath = path.join(projectRoot, '.codeyam', 'active-scenario.json');
190
+ try {
191
+ if (!fs.existsSync(activeScenarioPath)) {
192
+ scenarioCache = { data: null, timestamp: now };
193
+ return null;
194
+ }
195
+ const active = JSON.parse(fs.readFileSync(activeScenarioPath, 'utf-8'));
196
+ const scenarioId = active.scenarioId;
197
+ if (!scenarioId) {
198
+ // No active scenario — but may have a prototypeId for localStorage clearing
199
+ currentPrototypeId = active.prototypeId || null;
200
+ scenarioCache = { data: null, timestamp: now };
201
+ return null;
202
+ }
203
+ const dataFilePath = path.join(projectRoot, '.codeyam', 'editor-scenarios', `${scenarioId}.json`);
204
+ if (!fs.existsSync(dataFilePath)) {
205
+ console.log(`[editorProxy] Scenario data file not found: ${dataFilePath}`);
206
+ scenarioCache = { data: null, timestamp: now };
207
+ return null;
208
+ }
209
+ const rawData = JSON.parse(fs.readFileSync(dataFilePath, 'utf-8'));
210
+ // Extract session config for cookie injection
211
+ sessionConfig = rawData.session || null;
212
+ // Extract localStorage config for HTML injection
213
+ localStorageConfig = rawData.localStorage || null;
214
+ activeScenarioId = scenarioId;
215
+ // Type-aware: for seed-based scenarios, only serve externalApis via proxy
216
+ const scenarioType = active.type || rawData.type || null;
217
+ let mockData;
218
+ if ((scenarioType === 'application' || scenarioType === 'user') &&
219
+ rawData.seed) {
220
+ // Seed-based scenario: only load externalApis as routes for the proxy
221
+ if (rawData.externalApis && typeof rawData.externalApis === 'object') {
222
+ mockData = { routes: rawData.externalApis };
223
+ }
224
+ else {
225
+ // No external APIs — proxy passes everything through
226
+ mockData = {};
227
+ }
228
+ }
229
+ else {
230
+ // Component/legacy scenario: load all data
231
+ mockData = rawData;
232
+ }
233
+ scenarioCache = { data: mockData, timestamp: now };
234
+ // Feed into mock state manager (smart reload handles dedup)
235
+ getMockStateManager().loadScenario(mockData);
236
+ return mockData;
237
+ }
238
+ catch (err) {
239
+ console.warn('[editorProxy] Error reading scenario data:', err);
240
+ scenarioCache = { data: null, timestamp: now };
241
+ return null;
242
+ }
243
+ }
244
+ /**
245
+ * Buffer the request body, up to MAX_BODY_SIZE.
246
+ * Returns null if the body exceeds the limit.
247
+ */
248
+ function bufferRequestBody(req) {
249
+ return new Promise((resolve) => {
250
+ const chunks = [];
251
+ let totalSize = 0;
252
+ req.on('data', (chunk) => {
253
+ totalSize += chunk.length;
254
+ if (totalSize > MAX_BODY_SIZE) {
255
+ resolve(null); // Too large — skip mock matching
256
+ req.resume(); // Drain remaining
257
+ }
258
+ else {
259
+ chunks.push(chunk);
260
+ }
261
+ });
262
+ req.on('end', () => {
263
+ if (totalSize > MAX_BODY_SIZE)
264
+ return; // Already resolved
265
+ resolve(Buffer.concat(chunks));
266
+ });
267
+ req.on('error', () => {
268
+ resolve(null);
269
+ });
270
+ });
271
+ }
272
+ /**
273
+ * Strip IPv6 bracket notation for use with http.request hostname.
274
+ * URL.hostname returns `[::1]` for IPv6 but http.request needs `::1`.
275
+ */
276
+ function stripIPv6Brackets(hostname) {
277
+ if (hostname.startsWith('[') && hostname.endsWith(']')) {
278
+ return hostname.slice(1, -1);
279
+ }
280
+ return hostname;
281
+ }
282
+ /**
283
+ * Forward a buffered request to the target dev server.
284
+ * Unlike the streaming forwardRequest, this replays a buffered body.
285
+ */
286
+ function forwardBufferedRequest(req, res, targetUrl, bodyBuffer) {
287
+ const target = new URL(targetUrl);
288
+ const hostname = stripIPv6Brackets(target.hostname);
289
+ const headers = { ...req.headers, host: `${target.hostname}:${target.port}` };
290
+ // Remove accept-encoding so the dev server returns uncompressed responses.
291
+ // The proxy injects a health script into HTML — this fails on compressed bodies.
292
+ delete headers['accept-encoding'];
293
+ // Update content-length if we have the body buffer
294
+ if (bodyBuffer) {
295
+ headers['content-length'] = String(bodyBuffer.length);
296
+ }
297
+ const options = {
298
+ hostname,
299
+ port: target.port,
300
+ path: req.url,
301
+ method: req.method,
302
+ headers,
303
+ };
304
+ const proxyReq = http.request(options, (proxyRes) => {
305
+ const status = proxyRes.statusCode || 200;
306
+ if (status >= 400) {
307
+ console.warn(`[editorProxy] Target returned ${status} for ${req.method} ${req.url}`);
308
+ }
309
+ const headers = { ...proxyRes.headers };
310
+ injectSessionCookie(headers);
311
+ // Check if response is HTML — if so, buffer and inject health script
312
+ const contentType = proxyRes.headers['content-type'] || '';
313
+ if (contentType.includes('text/html')) {
314
+ resetPreviewHealth();
315
+ const chunks = [];
316
+ proxyRes.on('data', (chunk) => chunks.push(chunk));
317
+ proxyRes.on('end', () => {
318
+ const body = Buffer.concat(chunks).toString('utf-8');
319
+ const lsScript = buildLocalStorageScript(localStorageConfig, activeScenarioId || '', currentPrototypeId);
320
+ const injected = injectHealthScript(body, lsScript);
321
+ delete headers['content-length'];
322
+ delete headers['content-encoding'];
323
+ // Prevent browser from caching HTML responses — scenario switches
324
+ // serve different content from the same URL (seed data changes the
325
+ // rendered page but the proxy URL stays the same).
326
+ headers['cache-control'] = 'no-store, must-revalidate';
327
+ res.writeHead(status, headers);
328
+ res.end(injected);
329
+ });
330
+ return;
331
+ }
332
+ res.writeHead(status, headers);
333
+ proxyRes.pipe(res, { end: true });
334
+ });
335
+ proxyReq.on('error', (err) => {
336
+ console.warn(`[editorProxy] Forward error for ${req.method} ${req.url}: ${err.message}`);
337
+ if (!res.headersSent) {
338
+ res.writeHead(502, { 'Content-Type': 'text/plain' });
339
+ res.end('Bad Gateway — dev server unreachable');
340
+ }
341
+ });
342
+ if (bodyBuffer && bodyBuffer.length > 0) {
343
+ proxyReq.end(bodyBuffer);
344
+ }
345
+ else {
346
+ proxyReq.end();
347
+ }
348
+ }
349
+ /**
350
+ * Forward an HTTP request to the target dev server.
351
+ * For HTML responses: buffers body to inject health-check script.
352
+ * For non-HTML responses: pipes directly (no buffering).
353
+ */
354
+ function forwardRequest(req, res, targetUrl) {
355
+ const target = new URL(targetUrl);
356
+ const hostname = stripIPv6Brackets(target.hostname);
357
+ // Build headers, stripping accept-encoding so the dev server returns uncompressed
358
+ // responses. The proxy injects a health script into HTML — this fails on compressed bodies.
359
+ const { 'accept-encoding': _ae, ...forwardHeaders } = req.headers;
360
+ const options = {
361
+ hostname,
362
+ port: target.port,
363
+ path: req.url,
364
+ method: req.method,
365
+ headers: {
366
+ ...forwardHeaders,
367
+ host: `${target.hostname}:${target.port}`,
368
+ },
369
+ };
370
+ const proxyReq = http.request(options, (proxyRes) => {
371
+ const status = proxyRes.statusCode || 200;
372
+ if (status >= 400) {
373
+ console.warn(`[editorProxy] Target returned ${status} for ${req.method} ${req.url}`);
374
+ }
375
+ const headers = { ...proxyRes.headers };
376
+ injectSessionCookie(headers);
377
+ // Check if response is HTML — if so, buffer and inject health script
378
+ const contentType = proxyRes.headers['content-type'] || '';
379
+ if (contentType.includes('text/html')) {
380
+ // Reset health state for new page loads
381
+ resetPreviewHealth();
382
+ const chunks = [];
383
+ proxyRes.on('data', (chunk) => chunks.push(chunk));
384
+ proxyRes.on('end', () => {
385
+ const body = Buffer.concat(chunks).toString('utf-8');
386
+ const lsScript = buildLocalStorageScript(localStorageConfig, activeScenarioId || '', currentPrototypeId);
387
+ const injected = injectHealthScript(body, lsScript);
388
+ // Remove content-length since body size changed; use chunked transfer
389
+ delete headers['content-length'];
390
+ // Remove content-encoding since we're serving uncompressed
391
+ delete headers['content-encoding'];
392
+ // Prevent browser from caching HTML responses — scenario switches
393
+ // serve different content from the same URL (seed data changes the
394
+ // rendered page but the proxy URL stays the same).
395
+ headers['cache-control'] = 'no-store, must-revalidate';
396
+ res.writeHead(status, headers);
397
+ res.end(injected);
398
+ });
399
+ return;
400
+ }
401
+ res.writeHead(status, headers);
402
+ proxyRes.pipe(res, { end: true });
403
+ });
404
+ proxyReq.on('error', (err) => {
405
+ console.warn(`[editorProxy] Forward error for ${req.method} ${req.url}: ${err.message}`);
406
+ if (!res.headersSent) {
407
+ res.writeHead(502, { 'Content-Type': 'text/plain' });
408
+ res.end('Bad Gateway — dev server unreachable');
409
+ }
410
+ });
411
+ req.pipe(proxyReq, { end: true });
412
+ }
413
+ /**
414
+ * Inject or clear the session-token cookie on proxied responses.
415
+ * When a scenario has session.cookieValue, sets the cookie to auto-log the user in.
416
+ * When a scenario has no session field (null), clears any existing session cookie.
417
+ * When sessionConfig is undefined (no scenario loaded yet), does nothing.
418
+ */
419
+ function injectSessionCookie(headers) {
420
+ if (sessionConfig === undefined)
421
+ return;
422
+ let cookie;
423
+ if (sessionConfig?.cookieValue) {
424
+ cookie = `session-token=${sessionConfig.cookieValue}; Path=/; SameSite=Lax`;
425
+ }
426
+ else {
427
+ // No session config — clear any existing session cookie
428
+ cookie = `session-token=; Path=/; Max-Age=0`;
429
+ }
430
+ const existing = headers['set-cookie'];
431
+ if (existing) {
432
+ headers['set-cookie'] = [
433
+ ...(Array.isArray(existing) ? existing : [existing]),
434
+ cookie,
435
+ ];
436
+ }
437
+ else {
438
+ headers['set-cookie'] = [cookie];
439
+ }
440
+ }
441
+ /**
442
+ * Get the current session config (for testing).
443
+ */
444
+ export function getSessionConfig() {
445
+ return sessionConfig;
446
+ }
447
+ /**
448
+ * Get the current localStorage config (for testing and script generation).
449
+ */
450
+ export function getLocalStorageConfig() {
451
+ return localStorageConfig;
452
+ }
453
+ /**
454
+ * Get the active scenario ID (for testing and script generation).
455
+ */
456
+ export function getActiveScenarioId() {
457
+ return activeScenarioId;
458
+ }
459
+ /**
460
+ * Get the current prototype ID (for testing).
461
+ */
462
+ export function getCurrentPrototypeId() {
463
+ return currentPrototypeId;
464
+ }
465
+ /**
466
+ * Build a script tag that seeds localStorage with scenario data on first load.
467
+ * Gated by scenario ID — only seeds when the scenario changes, preserving
468
+ * interactive modifications across page reloads / HMR.
469
+ *
470
+ * Returns empty string if no localStorage config is provided.
471
+ */
472
+ export function buildLocalStorageScript(localStorageConfig, scenarioId, prototypeId) {
473
+ // null/undefined means no localStorage config at all — but if we have a
474
+ // prototypeId, emit a one-time localStorage.clear() to flush stale data
475
+ // from a previous prototype session.
476
+ if (!localStorageConfig || typeof localStorageConfig !== 'object') {
477
+ if (prototypeId) {
478
+ return `<script data-codeyam-ls>
479
+ (function() {
480
+ if (localStorage.getItem('__codeyam_proto__') === ${JSON.stringify(prototypeId)}) return;
481
+ localStorage.clear();
482
+ localStorage.setItem('__codeyam_proto__', ${JSON.stringify(prototypeId)});
483
+ })();
484
+ </script>`;
485
+ }
486
+ return '';
487
+ }
488
+ // Even an empty object needs a cleanup script — switching from a scenario
489
+ // with localStorage data to one without must clear the previous keys.
490
+ const entries = Object.entries(localStorageConfig);
491
+ const keys = entries.map(([k]) => k);
492
+ // Build setItem calls — stringify non-string values
493
+ const setStatements = entries
494
+ .map(([key, value]) => {
495
+ const serialized = typeof value === 'string' ? value : JSON.stringify(value);
496
+ return `localStorage.setItem(${JSON.stringify(key)}, ${JSON.stringify(serialized)});`;
497
+ })
498
+ .join('\n');
499
+ return `<script data-codeyam-ls>
500
+ (function() {
501
+ if (localStorage.getItem('__codeyam_ls_sid__') === ${JSON.stringify(scenarioId)}) return;
502
+ var prev = JSON.parse(localStorage.getItem('__codeyam_ls_keys__') || '[]');
503
+ for (var i = 0; i < prev.length; i++) localStorage.removeItem(prev[i]);
504
+ ${setStatements}
505
+ localStorage.setItem('__codeyam_ls_keys__', ${JSON.stringify(JSON.stringify(keys))});
506
+ localStorage.setItem('__codeyam_ls_sid__', ${JSON.stringify(scenarioId)});
507
+ })();
508
+ </script>`;
509
+ }
510
+ /**
511
+ * Inject the health-check script (and optional localStorage script) into an HTML response body.
512
+ * Inserts before </head> if present, otherwise before </body>, otherwise appends.
513
+ * When a localStorageScript is provided, it's injected BEFORE the health script
514
+ * so localStorage is populated before the app loads.
515
+ */
516
+ export function injectHealthScript(html, localStorageScript) {
517
+ const scripts = (localStorageScript || '') + PREVIEW_HEALTH_SCRIPT;
518
+ if (html.includes('</head>')) {
519
+ return html.replace('</head>', scripts + '</head>');
520
+ }
521
+ if (html.includes('</body>')) {
522
+ return html.replace('</body>', scripts + '</body>');
523
+ }
524
+ return html + scripts;
525
+ }
526
+ /**
527
+ * Handle POST /__codeyam__/preview-health — store health data in globalThis.
528
+ */
529
+ function handlePreviewHealthPost(req, res) {
530
+ const chunks = [];
531
+ req.on('data', (chunk) => chunks.push(chunk));
532
+ req.on('end', () => {
533
+ try {
534
+ const body = JSON.parse(Buffer.concat(chunks).toString('utf-8'));
535
+ const current = getPreviewHealth() || {
536
+ errors: [],
537
+ loaded: false,
538
+ hasContent: false,
539
+ url: '',
540
+ lastUpdated: 0,
541
+ };
542
+ if (body.errors && Array.isArray(body.errors)) {
543
+ current.errors = current.errors.concat(body.errors);
544
+ }
545
+ if (body.loaded !== undefined) {
546
+ current.loaded = body.loaded;
547
+ }
548
+ if (body.hasContent !== undefined) {
549
+ current.hasContent = body.hasContent;
550
+ }
551
+ if (body.url) {
552
+ current.url = body.url;
553
+ }
554
+ current.lastUpdated = Date.now();
555
+ setPreviewHealth(current);
556
+ }
557
+ catch {
558
+ // Ignore malformed JSON
559
+ }
560
+ res.writeHead(204);
561
+ res.end();
562
+ });
563
+ }
564
+ /**
565
+ * Handle WebSocket upgrade by piping to the target dev server.
566
+ */
567
+ function handleUpgrade(req, socket, head, targetUrl) {
568
+ const target = new URL(targetUrl);
569
+ const hostname = stripIPv6Brackets(target.hostname);
570
+ const port = parseInt(target.port, 10) || 80;
571
+ console.log(`[editorProxy] WebSocket upgrade: ${req.url} → ${hostname}:${port}`);
572
+ const proxySocket = net.connect(port, hostname, () => {
573
+ // Reconstruct the HTTP upgrade request
574
+ const requestLine = `${req.method} ${req.url} HTTP/${req.httpVersion}\r\n`;
575
+ const headers = Object.entries(req.headers)
576
+ .filter(([, v]) => v != null)
577
+ .map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(', ') : v}`)
578
+ .join('\r\n');
579
+ proxySocket.write(requestLine + headers + '\r\n\r\n');
580
+ if (head.length > 0) {
581
+ proxySocket.write(head);
582
+ }
583
+ // Pipe both directions
584
+ proxySocket.pipe(socket, { end: true });
585
+ socket.pipe(proxySocket, { end: true });
586
+ });
587
+ proxySocket.on('error', (err) => {
588
+ console.warn(`[editorProxy] WebSocket proxy error: ${err.message}`);
589
+ socket.destroy();
590
+ });
591
+ socket.on('error', () => {
592
+ proxySocket.destroy();
593
+ });
594
+ }
595
+ /**
596
+ * Write proxy-config.json so the preload module can discover the proxy.
597
+ */
598
+ function writeProxyConfig(proxyPort, targetUrl) {
599
+ const projectRoot = getProjectRoot() || process.env.CODEYAM_ROOT_PATH || process.cwd();
600
+ const configPath = path.join(projectRoot, '.codeyam', 'proxy-config.json');
601
+ try {
602
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
603
+ fs.writeFileSync(configPath, JSON.stringify({
604
+ proxyUrl: `http://localhost:${proxyPort}`,
605
+ devServerUrl: targetUrl,
606
+ }), 'utf-8');
607
+ console.log(`[editorProxy] Wrote proxy config to ${configPath}`);
608
+ }
609
+ catch (err) {
610
+ console.warn('[editorProxy] Failed to write proxy-config.json:', err);
611
+ }
612
+ }
613
+ /**
614
+ * Remove proxy-config.json on proxy stop.
615
+ */
616
+ function removeProxyConfig() {
617
+ const projectRoot = getProjectRoot() || process.env.CODEYAM_ROOT_PATH || process.cwd();
618
+ const configPath = path.join(projectRoot, '.codeyam', 'proxy-config.json');
619
+ try {
620
+ if (fs.existsSync(configPath)) {
621
+ fs.unlinkSync(configPath);
622
+ }
623
+ }
624
+ catch {
625
+ // Best effort
626
+ }
627
+ }
628
+ /**
629
+ * Start the editor proxy server.
630
+ * Intercepts requests to API routes matching the active scenario, forwards everything else.
631
+ * Supports all HTTP methods (GET, POST, PUT, DELETE, PATCH) with body buffering.
632
+ */
633
+ export async function startEditorProxy(options) {
634
+ // If proxy is already running, reuse it (prevents second tab from killing first tab's proxy)
635
+ const existing = getProxyState();
636
+ if (existing) {
637
+ console.log(`[editorProxy] Proxy already running on port ${existing.port} → ${existing.targetUrl}`);
638
+ return { port: existing.port };
639
+ }
640
+ // Stop any leftover state (shouldn't happen, but defensive)
641
+ await stopEditorProxy();
642
+ let targetUrl = normalizeTargetUrl(options.targetUrl);
643
+ let port = options.port;
644
+ // When the target is localhost, probe to find the correct loopback address.
645
+ // Dev servers may bind to IPv4 (127.0.0.1) or IPv6 (::1) — Vite 6 on macOS
646
+ // binds to ::1 by default. We need to match the actual binding.
647
+ try {
648
+ const parsed = new URL(targetUrl);
649
+ if (parsed.hostname === 'localhost') {
650
+ const targetPort = parseInt(parsed.port || '80', 10);
651
+ const resolvedHost = await resolveLoopbackAddress(targetPort);
652
+ if (resolvedHost) {
653
+ parsed.hostname = resolvedHost;
654
+ targetUrl = parsed.toString().replace(/\/$/, '');
655
+ console.log(`[editorProxy] Resolved localhost to ${resolvedHost} for port ${targetPort}`);
656
+ }
657
+ }
658
+ }
659
+ catch {
660
+ // Keep original targetUrl
661
+ }
662
+ console.log(`[editorProxy] Starting proxy (requested port ${port}, target ${targetUrl})`);
663
+ const mockState = getMockStateManager();
664
+ const server = http.createServer((req, res) => {
665
+ void (async () => {
666
+ const parsedUrl = new URL(req.url || '/', `http://localhost:${port}`);
667
+ const pathname = parsedUrl.pathname;
668
+ const method = req.method || 'GET';
669
+ // CORS preflight — permissive 204 for browser cross-origin requests
670
+ if (method === 'OPTIONS') {
671
+ res.writeHead(204, {
672
+ 'Access-Control-Allow-Origin': '*',
673
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
674
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With',
675
+ 'Access-Control-Max-Age': '86400',
676
+ });
677
+ res.end();
678
+ return;
679
+ }
680
+ // Intercept preview health reports from the injected script
681
+ if (method === 'POST' && pathname === '/__codeyam__/preview-health') {
682
+ handlePreviewHealthPost(req, res);
683
+ return;
684
+ }
685
+ // Load scenario data (also feeds MockStateManager)
686
+ readScenarioData();
687
+ // For methods that may carry a body, buffer it first
688
+ const needsBody = method === 'POST' ||
689
+ method === 'PUT' ||
690
+ method === 'DELETE' ||
691
+ method === 'PATCH';
692
+ if (needsBody) {
693
+ const bodyBuffer = await bufferRequestBody(req);
694
+ if (bodyBuffer === null) {
695
+ // Body too large — forward without mock matching
696
+ forwardBufferedRequest(req, res, targetUrl, null);
697
+ return;
698
+ }
699
+ // Try to parse body as JSON for mock matching
700
+ let parsedBody = undefined;
701
+ if (bodyBuffer.length > 0) {
702
+ try {
703
+ parsedBody = JSON.parse(bodyBuffer.toString('utf-8'));
704
+ }
705
+ catch {
706
+ // Not JSON — that's fine, still try mock matching without parsed body
707
+ }
708
+ }
709
+ const match = mockState.matchRequest(method, pathname, parsedBody);
710
+ if (match) {
711
+ console.log(`[editorProxy] Intercepted ${method} ${pathname} → mock response (status ${match.status})`);
712
+ res.writeHead(match.status, {
713
+ 'Content-Type': 'application/json',
714
+ 'Access-Control-Allow-Origin': '*',
715
+ 'X-CodeYam-Proxy': 'scenario-data',
716
+ 'Cache-Control': 'no-store',
717
+ });
718
+ res.end(match.body != null ? JSON.stringify(match.body) : '');
719
+ return;
720
+ }
721
+ // No mock match — forward with buffered body
722
+ forwardBufferedRequest(req, res, targetUrl, bodyBuffer);
723
+ return;
724
+ }
725
+ // GET, HEAD, etc. — try mock matching (no body)
726
+ const match = mockState.matchRequest(method, pathname);
727
+ if (match) {
728
+ console.log(`[editorProxy] Intercepted ${method} ${pathname} → mock response (status ${match.status})`);
729
+ res.writeHead(match.status, {
730
+ 'Content-Type': 'application/json',
731
+ 'Access-Control-Allow-Origin': '*',
732
+ 'X-CodeYam-Proxy': 'scenario-data',
733
+ 'Cache-Control': 'no-store',
734
+ });
735
+ res.end(match.body != null ? JSON.stringify(match.body) : '');
736
+ return;
737
+ }
738
+ // Forward everything else to the dev server
739
+ forwardRequest(req, res, targetUrl);
740
+ })();
741
+ });
742
+ // Handle WebSocket upgrades (for HMR)
743
+ server.on('upgrade', (req, socket, head) => {
744
+ handleUpgrade(req, socket, head, targetUrl);
745
+ });
746
+ // Try to bind, with port fallback
747
+ const maxAttempts = 10;
748
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
749
+ const currentPort = port + attempt;
750
+ try {
751
+ await new Promise((resolve, reject) => {
752
+ server.once('error', reject);
753
+ server.listen(currentPort, '0.0.0.0', () => {
754
+ server.removeListener('error', reject);
755
+ resolve();
756
+ });
757
+ });
758
+ // When port 0 is requested, the OS assigns an ephemeral port
759
+ const addr = server.address();
760
+ port =
761
+ typeof addr === 'object' && addr !== null ? addr.port : currentPort;
762
+ const state = { server, port, targetUrl };
763
+ setProxyState(state);
764
+ // Write proxy-config.json for the preload module
765
+ writeProxyConfig(port, targetUrl);
766
+ console.log(`[editorProxy] Proxy started on port ${port}, forwarding to ${targetUrl}`);
767
+ return { port };
768
+ }
769
+ catch (err) {
770
+ if (err?.code === 'EADDRINUSE' && attempt < maxAttempts - 1) {
771
+ console.log(`[editorProxy] Port ${currentPort} in use, trying ${currentPort + 1}`);
772
+ continue;
773
+ }
774
+ console.error(`[editorProxy] Failed to start proxy:`, err);
775
+ return null;
776
+ }
777
+ }
778
+ return null;
779
+ }
780
+ /**
781
+ * Stop the editor proxy server.
782
+ */
783
+ export async function stopEditorProxy() {
784
+ const state = getProxyState();
785
+ if (!state)
786
+ return;
787
+ console.log(`[editorProxy] Stopping proxy on port ${state.port}`);
788
+ removeProxyConfig();
789
+ return new Promise((resolve) => {
790
+ state.server.close(() => {
791
+ console.log('[editorProxy] Proxy stopped');
792
+ resolve();
793
+ });
794
+ setProxyState(null);
795
+ // Force-close after 2s if graceful close doesn't happen
796
+ setTimeout(resolve, 2000);
797
+ });
798
+ }
799
+ /**
800
+ * Invalidate the scenario data cache (e.g., after writing a new active-scenario.json).
801
+ */
802
+ export function invalidateScenarioCache() {
803
+ scenarioCache = { data: null, timestamp: 0 };
804
+ sessionConfig = undefined;
805
+ localStorageConfig = null;
806
+ activeScenarioId = null;
807
+ currentPrototypeId = null;
808
+ }
809
+ /**
810
+ * Verify that the proxy can successfully forward a request to the target dev server.
811
+ * Makes a HEAD request through the proxy and checks that it gets a response (any status).
812
+ * Returns false if the proxy isn't running or if the request fails entirely.
813
+ */
814
+ export async function verifyProxyForwarding() {
815
+ const state = getProxyState();
816
+ if (!state) {
817
+ console.warn('[editorProxy] Cannot verify — proxy is not running');
818
+ return false;
819
+ }
820
+ try {
821
+ const response = await fetch(`http://127.0.0.1:${state.port}/`, {
822
+ method: 'HEAD',
823
+ signal: AbortSignal.timeout(5000),
824
+ });
825
+ // Any response from the target (even 404) means forwarding works.
826
+ // Only 502 (our own Bad Gateway) means the target is unreachable.
827
+ if (response.status === 502) {
828
+ console.warn(`[editorProxy] Verification failed — proxy returned 502 (target unreachable)`);
829
+ return false;
830
+ }
831
+ console.log(`[editorProxy] Verification passed — proxy forwarding to ${state.targetUrl} (status ${response.status})`);
832
+ return true;
833
+ }
834
+ catch (err) {
835
+ console.warn(`[editorProxy] Verification failed — could not reach proxy on port ${state.port}`);
836
+ return false;
837
+ }
838
+ }
839
+ /**
840
+ * Ensure the proxy is running. If it's not, start it using the current dev server URL.
841
+ * Returns the proxy URL once ready, or null if it can't be started.
842
+ *
843
+ * Used by capture flows to guarantee the proxy is listening before Playwright navigates.
844
+ */
845
+ export async function ensureProxyRunning() {
846
+ // Already running?
847
+ const existing = getProxyUrl();
848
+ if (existing) {
849
+ console.log(`[editorProxy] Proxy already running at ${existing}`);
850
+ return existing;
851
+ }
852
+ // Try to start it — we need the dev server URL
853
+ const devServer = globalThis.__codeyam_editor_dev_server__;
854
+ if (!devServer || devServer.status !== 'running' || !devServer.url) {
855
+ console.log('[editorProxy] Cannot start proxy — dev server not running');
856
+ return null;
857
+ }
858
+ const codeyamPort = parseInt(process.env.CODEYAM_PORT || '3111', 10);
859
+ const { proxyPort } = computeEditorPorts(codeyamPort);
860
+ console.log(`[editorProxy] Proxy not running, starting on-demand (port ${proxyPort}, target ${devServer.url})`);
861
+ const result = await startEditorProxy({
862
+ port: proxyPort,
863
+ targetUrl: devServer.url,
864
+ });
865
+ if (result) {
866
+ const url = `http://localhost:${result.port}`;
867
+ console.log(`[editorProxy] On-demand proxy started at ${url}`);
868
+ return url;
869
+ }
870
+ console.error('[editorProxy] Failed to start on-demand proxy');
871
+ return null;
872
+ }
873
+ /**
874
+ * Test-only export: trigger readScenarioData so tests can verify session config extraction.
875
+ */
876
+ export const _readScenarioDataForTest = readScenarioData;
877
+ //# sourceMappingURL=editorProxy.js.map