@codeyam/codeyam-cli 0.1.0-staging.5fba2e4 → 0.1.0-staging.693b02d

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 (510) 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 +6 -6
  4. package/analyzer-template/packages/ai/package.json +1 -1
  5. package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +135 -0
  6. package/analyzer-template/packages/ai/src/lib/astScopes/nodeToSource.ts +19 -0
  7. package/analyzer-template/packages/ai/src/lib/astScopes/paths.ts +11 -4
  8. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +36 -9
  9. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.ts +10 -3
  10. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +16 -6
  11. package/analyzer-template/packages/analyze/index.ts +4 -1
  12. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +28 -2
  13. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +5 -36
  14. package/analyzer-template/packages/analyze/src/lib/files/analyze/findOrCreateEntity.ts +10 -6
  15. package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +9 -12
  16. package/analyzer-template/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.ts +21 -0
  17. package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +82 -10
  18. package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +4 -0
  19. package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +4 -0
  20. package/analyzer-template/packages/analyze/src/lib/files/analyzeNextRoute.ts +8 -3
  21. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +239 -58
  22. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +1684 -1462
  23. package/analyzer-template/packages/aws/package.json +7 -7
  24. package/analyzer-template/packages/database/package.json +3 -3
  25. package/analyzer-template/packages/database/src/lib/kysely/tables/editorScenariosTable.ts +82 -0
  26. package/analyzer-template/packages/database/src/lib/loadAnalysis.ts +25 -15
  27. package/analyzer-template/packages/database/src/lib/loadEntities.ts +0 -6
  28. package/analyzer-template/packages/database/src/lib/loadEntity.ts +19 -8
  29. package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +0 -65
  30. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts +5 -0
  31. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts.map +1 -1
  32. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js +84 -0
  33. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -1
  34. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.d.ts.map +1 -1
  35. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js +7 -1
  36. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js.map +1 -1
  37. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts.map +1 -1
  38. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js +0 -6
  39. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js.map +1 -1
  40. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.d.ts +4 -1
  41. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.d.ts.map +1 -1
  42. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.js +5 -5
  43. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.js.map +1 -1
  44. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
  45. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +0 -25
  46. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js.map +1 -1
  47. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts +3 -1
  48. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts.map +1 -1
  49. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js +22 -1
  50. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  51. package/analyzer-template/packages/utils/src/lib/fs/rsyncCopy.ts +27 -0
  52. package/analyzer-template/project/analyzeFileEntities.ts +26 -0
  53. package/analyzer-template/project/runMultiScenarioServer.ts +26 -3
  54. package/background/src/lib/virtualized/project/analyzeFileEntities.js +22 -0
  55. package/background/src/lib/virtualized/project/analyzeFileEntities.js.map +1 -1
  56. package/background/src/lib/virtualized/project/runMultiScenarioServer.js +23 -3
  57. package/background/src/lib/virtualized/project/runMultiScenarioServer.js.map +1 -1
  58. package/codeyam-cli/src/cli.js +24 -0
  59. package/codeyam-cli/src/cli.js.map +1 -1
  60. package/codeyam-cli/src/commands/__tests__/editor.analyzeImportsArgs.test.js +47 -0
  61. package/codeyam-cli/src/commands/__tests__/editor.analyzeImportsArgs.test.js.map +1 -0
  62. package/codeyam-cli/src/commands/__tests__/editor.auditNoAutoAnalysis.test.js +71 -0
  63. package/codeyam-cli/src/commands/__tests__/editor.auditNoAutoAnalysis.test.js.map +1 -0
  64. package/codeyam-cli/src/commands/__tests__/editor.designSystem.test.js +30 -0
  65. package/codeyam-cli/src/commands/__tests__/editor.designSystem.test.js.map +1 -0
  66. package/codeyam-cli/src/commands/__tests__/editor.isolateArgs.test.js +51 -0
  67. package/codeyam-cli/src/commands/__tests__/editor.isolateArgs.test.js.map +1 -0
  68. package/codeyam-cli/src/commands/__tests__/editor.statePersistence.test.js +55 -0
  69. package/codeyam-cli/src/commands/__tests__/editor.statePersistence.test.js.map +1 -0
  70. package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js +56 -0
  71. package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js.map +1 -0
  72. package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js +137 -47
  73. package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js.map +1 -1
  74. package/codeyam-cli/src/commands/editor.js +4218 -674
  75. package/codeyam-cli/src/commands/editor.js.map +1 -1
  76. package/codeyam-cli/src/commands/editorAnalyzeImportsArgs.js +23 -0
  77. package/codeyam-cli/src/commands/editorAnalyzeImportsArgs.js.map +1 -0
  78. package/codeyam-cli/src/commands/editorIsolateArgs.js +25 -0
  79. package/codeyam-cli/src/commands/editorIsolateArgs.js.map +1 -0
  80. package/codeyam-cli/src/commands/init.js +89 -34
  81. package/codeyam-cli/src/commands/init.js.map +1 -1
  82. package/codeyam-cli/src/commands/telemetry.js +37 -0
  83. package/codeyam-cli/src/commands/telemetry.js.map +1 -0
  84. package/codeyam-cli/src/data/designSystems.js +27 -0
  85. package/codeyam-cli/src/data/designSystems.js.map +1 -0
  86. package/codeyam-cli/src/data/techStacks.js +1 -1
  87. package/codeyam-cli/src/utils/__tests__/analyzerFinalization.test.js +173 -0
  88. package/codeyam-cli/src/utils/__tests__/analyzerFinalization.test.js.map +1 -0
  89. package/codeyam-cli/src/utils/__tests__/backgroundServer.test.js +46 -0
  90. package/codeyam-cli/src/utils/__tests__/backgroundServer.test.js.map +1 -0
  91. package/codeyam-cli/src/utils/__tests__/devServerState.test.js +93 -1
  92. package/codeyam-cli/src/utils/__tests__/devServerState.test.js.map +1 -1
  93. package/codeyam-cli/src/utils/__tests__/editorApi.test.js +62 -8
  94. package/codeyam-cli/src/utils/__tests__/editorApi.test.js.map +1 -1
  95. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +3526 -1
  96. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
  97. package/codeyam-cli/src/utils/__tests__/editorBroadcastViewport.test.js +76 -0
  98. package/codeyam-cli/src/utils/__tests__/editorBroadcastViewport.test.js.map +1 -0
  99. package/codeyam-cli/src/utils/__tests__/editorCaptureScenarioSeeding.test.js +137 -0
  100. package/codeyam-cli/src/utils/__tests__/editorCaptureScenarioSeeding.test.js.map +1 -0
  101. package/codeyam-cli/src/utils/__tests__/editorDeleteScenario.test.js +100 -0
  102. package/codeyam-cli/src/utils/__tests__/editorDeleteScenario.test.js.map +1 -0
  103. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js +76 -3
  104. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js.map +1 -1
  105. package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js +381 -0
  106. package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js.map +1 -0
  107. package/codeyam-cli/src/utils/__tests__/editorGuardMiddleware.test.js +67 -0
  108. package/codeyam-cli/src/utils/__tests__/editorGuardMiddleware.test.js.map +1 -0
  109. package/codeyam-cli/src/utils/__tests__/editorLoaderHelpers.test.js +202 -1
  110. package/codeyam-cli/src/utils/__tests__/editorLoaderHelpers.test.js.map +1 -1
  111. package/codeyam-cli/src/utils/__tests__/editorMigration.test.js +435 -0
  112. package/codeyam-cli/src/utils/__tests__/editorMigration.test.js.map +1 -0
  113. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js +96 -1
  114. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js.map +1 -1
  115. package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js +144 -1
  116. package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js.map +1 -1
  117. package/codeyam-cli/src/utils/__tests__/editorRoadmap.test.js +1108 -0
  118. package/codeyam-cli/src/utils/__tests__/editorRoadmap.test.js.map +1 -0
  119. package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js +190 -0
  120. package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js.map +1 -1
  121. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js +1494 -1
  122. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -1
  123. package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js +201 -1
  124. package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js.map +1 -1
  125. package/codeyam-cli/src/utils/__tests__/editorSeedAdapterPrismaValidation.test.js +143 -0
  126. package/codeyam-cli/src/utils/__tests__/editorSeedAdapterPrismaValidation.test.js.map +1 -0
  127. package/codeyam-cli/src/utils/__tests__/editorSessionFilter.test.js +66 -0
  128. package/codeyam-cli/src/utils/__tests__/editorSessionFilter.test.js.map +1 -0
  129. package/codeyam-cli/src/utils/__tests__/editorShouldRevalidate.test.js +53 -0
  130. package/codeyam-cli/src/utils/__tests__/editorShouldRevalidate.test.js.map +1 -0
  131. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js +395 -11
  132. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js.map +1 -1
  133. package/codeyam-cli/src/utils/__tests__/envFile.test.js +125 -0
  134. package/codeyam-cli/src/utils/__tests__/envFile.test.js.map +1 -0
  135. package/codeyam-cli/src/utils/__tests__/glossaryAdd.test.js +177 -0
  136. package/codeyam-cli/src/utils/__tests__/glossaryAdd.test.js.map +1 -0
  137. package/codeyam-cli/src/utils/__tests__/handoffContext.test.js +500 -0
  138. package/codeyam-cli/src/utils/__tests__/handoffContext.test.js.map +1 -0
  139. package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js +16 -1
  140. package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js.map +1 -1
  141. package/codeyam-cli/src/utils/__tests__/manualEntityAnalysis.test.js +302 -0
  142. package/codeyam-cli/src/utils/__tests__/manualEntityAnalysis.test.js.map +1 -0
  143. package/codeyam-cli/src/utils/__tests__/parseRegisterArg.test.js +30 -2
  144. package/codeyam-cli/src/utils/__tests__/parseRegisterArg.test.js.map +1 -1
  145. package/codeyam-cli/src/utils/__tests__/registerScenarioResult.test.js +127 -0
  146. package/codeyam-cli/src/utils/__tests__/registerScenarioResult.test.js.map +1 -0
  147. package/codeyam-cli/src/utils/__tests__/routePatternMatching.test.js +118 -0
  148. package/codeyam-cli/src/utils/__tests__/routePatternMatching.test.js.map +1 -0
  149. package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js +284 -0
  150. package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js.map +1 -0
  151. package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js +649 -223
  152. package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js.map +1 -1
  153. package/codeyam-cli/src/utils/__tests__/screenshotHash.test.js +84 -0
  154. package/codeyam-cli/src/utils/__tests__/screenshotHash.test.js.map +1 -0
  155. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +1 -0
  156. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  157. package/codeyam-cli/src/utils/__tests__/telemetry.test.js +159 -0
  158. package/codeyam-cli/src/utils/__tests__/telemetry.test.js.map +1 -0
  159. package/codeyam-cli/src/utils/__tests__/testRunner.test.js +216 -0
  160. package/codeyam-cli/src/utils/__tests__/testRunner.test.js.map +1 -0
  161. package/codeyam-cli/src/utils/__tests__/webappDetection.test.js +6 -0
  162. package/codeyam-cli/src/utils/__tests__/webappDetection.test.js.map +1 -1
  163. package/codeyam-cli/src/utils/analysisRunner.js +39 -8
  164. package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
  165. package/codeyam-cli/src/utils/analyzer.js +19 -0
  166. package/codeyam-cli/src/utils/analyzer.js.map +1 -1
  167. package/codeyam-cli/src/utils/analyzerFinalization.js +100 -0
  168. package/codeyam-cli/src/utils/analyzerFinalization.js.map +1 -0
  169. package/codeyam-cli/src/utils/backgroundServer.js +14 -47
  170. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  171. package/codeyam-cli/src/utils/database.js +37 -2
  172. package/codeyam-cli/src/utils/database.js.map +1 -1
  173. package/codeyam-cli/src/utils/designSystemShowcase.js +810 -0
  174. package/codeyam-cli/src/utils/designSystemShowcase.js.map +1 -0
  175. package/codeyam-cli/src/utils/devServerState.js +32 -0
  176. package/codeyam-cli/src/utils/devServerState.js.map +1 -1
  177. package/codeyam-cli/src/utils/editorApi.js +27 -5
  178. package/codeyam-cli/src/utils/editorApi.js.map +1 -1
  179. package/codeyam-cli/src/utils/editorAudit.js +700 -10
  180. package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
  181. package/codeyam-cli/src/utils/editorBroadcastViewport.js +26 -0
  182. package/codeyam-cli/src/utils/editorBroadcastViewport.js.map +1 -0
  183. package/codeyam-cli/src/utils/editorDeleteScenario.js +67 -0
  184. package/codeyam-cli/src/utils/editorDeleteScenario.js.map +1 -0
  185. package/codeyam-cli/src/utils/editorEntityChangeStatus.js +13 -7
  186. package/codeyam-cli/src/utils/editorEntityChangeStatus.js.map +1 -1
  187. package/codeyam-cli/src/utils/editorEntityHelpers.js +144 -0
  188. package/codeyam-cli/src/utils/editorEntityHelpers.js.map +1 -0
  189. package/codeyam-cli/src/utils/editorGuard.js +36 -0
  190. package/codeyam-cli/src/utils/editorGuard.js.map +1 -0
  191. package/codeyam-cli/src/utils/editorLoaderHelpers.js +72 -1
  192. package/codeyam-cli/src/utils/editorLoaderHelpers.js.map +1 -1
  193. package/codeyam-cli/src/utils/editorMigration.js +224 -0
  194. package/codeyam-cli/src/utils/editorMigration.js.map +1 -0
  195. package/codeyam-cli/src/utils/editorPreview.js +33 -0
  196. package/codeyam-cli/src/utils/editorPreview.js.map +1 -1
  197. package/codeyam-cli/src/utils/editorRecapture.js +109 -0
  198. package/codeyam-cli/src/utils/editorRecapture.js.map +1 -0
  199. package/codeyam-cli/src/utils/editorRoadmap.js +574 -0
  200. package/codeyam-cli/src/utils/editorRoadmap.js.map +1 -0
  201. package/codeyam-cli/src/utils/editorScenarioSwitch.js +39 -2
  202. package/codeyam-cli/src/utils/editorScenarioSwitch.js.map +1 -1
  203. package/codeyam-cli/src/utils/editorScenarios.js +561 -0
  204. package/codeyam-cli/src/utils/editorScenarios.js.map +1 -1
  205. package/codeyam-cli/src/utils/editorSeedAdapter.js +308 -6
  206. package/codeyam-cli/src/utils/editorSeedAdapter.js.map +1 -1
  207. package/codeyam-cli/src/utils/editorShouldRevalidate.js +21 -0
  208. package/codeyam-cli/src/utils/editorShouldRevalidate.js.map +1 -0
  209. package/codeyam-cli/src/utils/entityChangeStatus.js +53 -6
  210. package/codeyam-cli/src/utils/entityChangeStatus.js.map +1 -1
  211. package/codeyam-cli/src/utils/entityChangeStatus.server.js +72 -3
  212. package/codeyam-cli/src/utils/entityChangeStatus.server.js.map +1 -1
  213. package/codeyam-cli/src/utils/envFile.js +90 -0
  214. package/codeyam-cli/src/utils/envFile.js.map +1 -0
  215. package/codeyam-cli/src/utils/fileWatcher.js +38 -0
  216. package/codeyam-cli/src/utils/fileWatcher.js.map +1 -1
  217. package/codeyam-cli/src/utils/glossaryAdd.js +74 -0
  218. package/codeyam-cli/src/utils/glossaryAdd.js.map +1 -0
  219. package/codeyam-cli/src/utils/handoffContext.js +257 -0
  220. package/codeyam-cli/src/utils/handoffContext.js.map +1 -0
  221. package/codeyam-cli/src/utils/install-skills.js +50 -6
  222. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  223. package/codeyam-cli/src/utils/manualEntityAnalysis.js +196 -0
  224. package/codeyam-cli/src/utils/manualEntityAnalysis.js.map +1 -0
  225. package/codeyam-cli/src/utils/parseRegisterArg.js.map +1 -1
  226. package/codeyam-cli/src/utils/progress.js +2 -2
  227. package/codeyam-cli/src/utils/progress.js.map +1 -1
  228. package/codeyam-cli/src/utils/queue/__tests__/job.interactiveStart.test.js +159 -0
  229. package/codeyam-cli/src/utils/queue/__tests__/job.interactiveStart.test.js.map +1 -0
  230. package/codeyam-cli/src/utils/queue/job.js +35 -6
  231. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  232. package/codeyam-cli/src/utils/registerScenarioResult.js +52 -0
  233. package/codeyam-cli/src/utils/registerScenarioResult.js.map +1 -0
  234. package/codeyam-cli/src/utils/routePatternMatching.js +129 -0
  235. package/codeyam-cli/src/utils/routePatternMatching.js.map +1 -0
  236. package/codeyam-cli/src/utils/scenarioCoverage.js +77 -0
  237. package/codeyam-cli/src/utils/scenarioCoverage.js.map +1 -0
  238. package/codeyam-cli/src/utils/scenariosManifest.js +275 -74
  239. package/codeyam-cli/src/utils/scenariosManifest.js.map +1 -1
  240. package/codeyam-cli/src/utils/screenshotHash.js +26 -0
  241. package/codeyam-cli/src/utils/screenshotHash.js.map +1 -0
  242. package/codeyam-cli/src/utils/serverState.js +30 -0
  243. package/codeyam-cli/src/utils/serverState.js.map +1 -1
  244. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +1 -0
  245. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  246. package/codeyam-cli/src/utils/simulationGateMiddleware.js +17 -1
  247. package/codeyam-cli/src/utils/simulationGateMiddleware.js.map +1 -1
  248. package/codeyam-cli/src/utils/slugUtils.js +25 -0
  249. package/codeyam-cli/src/utils/slugUtils.js.map +1 -0
  250. package/codeyam-cli/src/utils/syncMocksMiddleware.js +2 -2
  251. package/codeyam-cli/src/utils/syncMocksMiddleware.js.map +1 -1
  252. package/codeyam-cli/src/utils/techStackConfig.js +38 -0
  253. package/codeyam-cli/src/utils/techStackConfig.js.map +1 -0
  254. package/codeyam-cli/src/utils/techStackConfig.test.js +85 -0
  255. package/codeyam-cli/src/utils/techStackConfig.test.js.map +1 -0
  256. package/codeyam-cli/src/utils/telemetry.js +106 -0
  257. package/codeyam-cli/src/utils/telemetry.js.map +1 -0
  258. package/codeyam-cli/src/utils/telemetryMiddleware.js +22 -0
  259. package/codeyam-cli/src/utils/telemetryMiddleware.js.map +1 -0
  260. package/codeyam-cli/src/utils/testResultCache.js +53 -0
  261. package/codeyam-cli/src/utils/testResultCache.js.map +1 -0
  262. package/codeyam-cli/src/utils/testResultCache.server.js +81 -0
  263. package/codeyam-cli/src/utils/testResultCache.server.js.map +1 -0
  264. package/codeyam-cli/src/utils/testResultCache.server.test.js +187 -0
  265. package/codeyam-cli/src/utils/testResultCache.server.test.js.map +1 -0
  266. package/codeyam-cli/src/utils/testResultCache.test.js +230 -0
  267. package/codeyam-cli/src/utils/testResultCache.test.js.map +1 -0
  268. package/codeyam-cli/src/utils/testRunner.js +193 -1
  269. package/codeyam-cli/src/utils/testRunner.js.map +1 -1
  270. package/codeyam-cli/src/utils/webappDetection.js +4 -2
  271. package/codeyam-cli/src/utils/webappDetection.js.map +1 -1
  272. package/codeyam-cli/src/webserver/__tests__/api.interactive-switch-scenario.test.js +99 -0
  273. package/codeyam-cli/src/webserver/__tests__/api.interactive-switch-scenario.test.js.map +1 -0
  274. package/codeyam-cli/src/webserver/__tests__/buildPtyEnv.test.js +153 -0
  275. package/codeyam-cli/src/webserver/__tests__/buildPtyEnv.test.js.map +1 -0
  276. package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js +107 -0
  277. package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js.map +1 -0
  278. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js +591 -1
  279. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js.map +1 -1
  280. package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js +315 -0
  281. package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js.map +1 -0
  282. package/codeyam-cli/src/webserver/__tests__/stripClaudeCommand.test.js +135 -0
  283. package/codeyam-cli/src/webserver/__tests__/stripClaudeCommand.test.js.map +1 -0
  284. package/codeyam-cli/src/webserver/app/lib/clientErrors.js +86 -0
  285. package/codeyam-cli/src/webserver/app/lib/clientErrors.js.map +1 -0
  286. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  287. package/codeyam-cli/src/webserver/app/lib/git.js +3 -2
  288. package/codeyam-cli/src/webserver/app/lib/git.js.map +1 -1
  289. package/codeyam-cli/src/webserver/app/routes/api.interactive-switch-scenario.js +34 -0
  290. package/codeyam-cli/src/webserver/app/routes/api.interactive-switch-scenario.js.map +1 -0
  291. package/codeyam-cli/src/webserver/app/types/editor.js +8 -0
  292. package/codeyam-cli/src/webserver/app/types/editor.js.map +1 -0
  293. package/codeyam-cli/src/webserver/backgroundServer.js +60 -61
  294. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  295. package/codeyam-cli/src/webserver/build/client/assets/CopyButton-DTBZZfSk.js +1 -0
  296. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-BcgbViKV.js → EntityItem-BxclONWq.js} +3 -3
  297. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeBadge-CQgyEGV-.js +1 -0
  298. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-CQIG2qda.js → EntityTypeIcon-BsnEOJZ_.js} +1 -1
  299. package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-ByaELMbv.js +1 -0
  300. package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-6WjVfhxX.js +25 -0
  301. package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-ChX-Hp7W.js +3 -0
  302. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-BU_OAEMP.js → LoadingDots-By5zI316.js} +1 -1
  303. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-ceAyBX-H.js → LogViewer-C-9zQdXg.js} +3 -3
  304. package/codeyam-cli/src/webserver/build/client/assets/MiniClaudeChat-Bs2_Oua4.js +36 -0
  305. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-BzHcG7SE.js → ReportIssueModal-DQsceHVv.js} +2 -2
  306. package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-DThcm_9M.js +1 -0
  307. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-0DY_NKil.js → ScenarioViewer-Cl4oOA3A.js} +3 -3
  308. package/codeyam-cli/src/webserver/build/client/assets/Spinner-CIil5-gb.js +34 -0
  309. package/codeyam-cli/src/webserver/build/client/assets/TruncatedFilePath-CK7-NaPZ.js +1 -0
  310. package/codeyam-cli/src/webserver/build/client/assets/ViewportInspectBar-BqkA9zyZ.js +1 -0
  311. package/codeyam-cli/src/webserver/build/client/assets/{_index-DLxKhri3.js → _index-DnOgyseQ.js} +2 -2
  312. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BcY3q6nt.js → activity.(_tab)-DqM9hbNE.js} +3 -3
  313. package/codeyam-cli/src/webserver/build/client/assets/{addon-web-links-Duc5hnl7.js → addon-web-links-C58dYPwR.js} +1 -1
  314. package/codeyam-cli/src/webserver/build/client/assets/{agent-transcripts-Bni3iiUj.js → agent-transcripts-B8NCeOrm.js} +3 -3
  315. package/codeyam-cli/src/webserver/build/client/assets/api.editor-database-verify-l0sNRNKZ.js +1 -0
  316. package/codeyam-cli/src/webserver/build/client/assets/api.editor-github-verify-l0sNRNKZ.js +1 -0
  317. package/codeyam-cli/src/webserver/build/client/assets/api.editor-handoff-l0sNRNKZ.js +1 -0
  318. package/codeyam-cli/src/webserver/build/client/assets/api.editor-hosting-verify-l0sNRNKZ.js +1 -0
  319. package/codeyam-cli/src/webserver/build/client/assets/api.editor-recapture-stale-l0sNRNKZ.js +1 -0
  320. package/codeyam-cli/src/webserver/build/client/assets/api.editor-rename-scenario-l0sNRNKZ.js +1 -0
  321. package/codeyam-cli/src/webserver/build/client/assets/api.editor-roadmap-l0sNRNKZ.js +1 -0
  322. package/codeyam-cli/src/webserver/build/client/assets/api.editor-save-scenario-data-l0sNRNKZ.js +1 -0
  323. package/codeyam-cli/src/webserver/build/client/assets/api.editor-save-seed-state-l0sNRNKZ.js +1 -0
  324. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-coverage-l0sNRNKZ.js +1 -0
  325. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-prompt-l0sNRNKZ.js +1 -0
  326. package/codeyam-cli/src/webserver/build/client/assets/api.editor-schema-l0sNRNKZ.js +1 -0
  327. package/codeyam-cli/src/webserver/build/client/assets/api.editor-session-l0sNRNKZ.js +1 -0
  328. package/codeyam-cli/src/webserver/build/client/assets/api.editor-verify-routes-l0sNRNKZ.js +1 -0
  329. package/codeyam-cli/src/webserver/build/client/assets/api.interactive-switch-scenario-l0sNRNKZ.js +1 -0
  330. package/codeyam-cli/src/webserver/build/client/assets/{book-open-BYOypzCa.js → book-open-BFSIqZgO.js} +1 -1
  331. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-C_Pmso5S.js → chevron-down-B9fDzFVh.js} +1 -1
  332. package/codeyam-cli/src/webserver/build/client/assets/chunk-UVKPFVEO-Bmq2apuh.js +43 -0
  333. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-BVMi9VA5.js → circle-check-DLPObLUx.js} +1 -1
  334. package/codeyam-cli/src/webserver/build/client/assets/{copy-n2FB0_Sw.js → copy-DXEmO0TD.js} +1 -1
  335. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-CC6AbExI.js → createLucideIcon-BwyFiRot.js} +1 -1
  336. package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-Coe5NhbS.js +1 -0
  337. package/codeyam-cli/src/webserver/build/client/assets/{cy-logo-cli-CCKUIm0S.svg → cy-logo-cli-DoA97ML3.svg} +2 -2
  338. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-iRhRIFlp.js +1 -0
  339. package/codeyam-cli/src/webserver/build/client/assets/editor._tab-BZPBzV73.js +1 -0
  340. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-DhtVC4aI.js +161 -0
  341. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-C6fEYHrh.js +41 -0
  342. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-BF4oLwaE.js → entity._sha._-pc-vc6wO.js} +13 -12
  343. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-C8AyYgYT.js +6 -0
  344. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-DziaVQX1.js +6 -0
  345. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-BTcpgIpC.js +6 -0
  346. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-BMvVHNXU.js → entity._sha_.edit._scenarioId-D_O_ajfZ.js} +2 -2
  347. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-DTvKq3TY.js → entry.client-j1Vi0bco.js} +6 -6
  348. package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-Daa96Fr1.js +1 -0
  349. package/codeyam-cli/src/webserver/build/client/assets/files-kuny2Q_s.js +1 -0
  350. package/codeyam-cli/src/webserver/build/client/assets/git-DgCZPMie.js +1 -0
  351. package/codeyam-cli/src/webserver/build/client/assets/globals-L-aUIeux.css +1 -0
  352. package/codeyam-cli/src/webserver/build/client/assets/{index-BcvgDzbZ.js → index-BliGSSpl.js} +1 -1
  353. package/codeyam-cli/src/webserver/build/client/assets/{index-yHOVb4rc.js → index-SqjQKTdH.js} +1 -1
  354. package/codeyam-cli/src/webserver/build/client/assets/{index-10oVnAAH.js → index-vyrZD2g4.js} +1 -1
  355. package/codeyam-cli/src/webserver/build/client/assets/jsx-runtime-D_zvdyIk.js +9 -0
  356. package/codeyam-cli/src/webserver/build/client/assets/labs-c3yLxSEp.js +1 -0
  357. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-DaAZ_H2w.js → loader-circle-D-q28GLF.js} +1 -1
  358. package/codeyam-cli/src/webserver/build/client/assets/manifest-79d0d81a.js +1 -0
  359. package/codeyam-cli/src/webserver/build/client/assets/memory-CEWIUC4t.js +101 -0
  360. package/codeyam-cli/src/webserver/build/client/assets/{pause-f5-1lKBt.js → pause-BP6fitdh.js} +1 -1
  361. package/codeyam-cli/src/webserver/build/client/assets/root-L2V0jea7.js +80 -0
  362. package/codeyam-cli/src/webserver/build/client/assets/{search-Di64LWVb.js → search-BooqacKS.js} +1 -1
  363. package/codeyam-cli/src/webserver/build/client/assets/settings-BM0nbryO.js +1 -0
  364. package/codeyam-cli/src/webserver/build/client/assets/simulations-ovy6FjRY.js +1 -0
  365. package/codeyam-cli/src/webserver/build/client/assets/{terminal-Br7MOqts.js → terminal-DHemCJIs.js} +1 -1
  366. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-BLdiCuG-.js → triangle-alert-D87ekDl8.js} +1 -1
  367. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-Dk0Tciqg.js +1 -0
  368. package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-C8QvIe05.js +2 -0
  369. package/codeyam-cli/src/webserver/build/client/assets/useReportContext-jkCytuYz.js +1 -0
  370. package/codeyam-cli/src/webserver/build/client/assets/useToast-BgqkixU9.js +1 -0
  371. package/codeyam-cli/src/webserver/build/client/sound-test.html +98 -0
  372. package/codeyam-cli/src/webserver/build/server/assets/analysisRunner-QgInFGdU.js +16 -0
  373. package/codeyam-cli/src/webserver/build/server/assets/index-zblh9auj.js +1 -0
  374. package/codeyam-cli/src/webserver/build/server/assets/init-DaE0CBjk.js +14 -0
  375. package/codeyam-cli/src/webserver/build/server/assets/progress-CHTtrxFG.js +1 -0
  376. package/codeyam-cli/src/webserver/build/server/assets/server-build-CNvgz1cC.js +853 -0
  377. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  378. package/codeyam-cli/src/webserver/build-info.json +5 -5
  379. package/codeyam-cli/src/webserver/editorProxy.js +512 -28
  380. package/codeyam-cli/src/webserver/editorProxy.js.map +1 -1
  381. package/codeyam-cli/src/webserver/idleDetector.js +130 -0
  382. package/codeyam-cli/src/webserver/idleDetector.js.map +1 -0
  383. package/codeyam-cli/src/webserver/mockStateEvents.js +28 -0
  384. package/codeyam-cli/src/webserver/mockStateEvents.js.map +1 -0
  385. package/codeyam-cli/src/webserver/public/sound-test.html +98 -0
  386. package/codeyam-cli/src/webserver/scripts/journalCapture.ts +53 -0
  387. package/codeyam-cli/src/webserver/server.js +192 -4
  388. package/codeyam-cli/src/webserver/server.js.map +1 -1
  389. package/codeyam-cli/src/webserver/terminalServer.js +369 -52
  390. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
  391. package/codeyam-cli/templates/__tests__/editor-step-hook.prompt-capture.test.ts +118 -0
  392. package/codeyam-cli/templates/chrome-extension-react/README.md +46 -0
  393. package/codeyam-cli/templates/chrome-extension-react/package.json +1 -0
  394. package/codeyam-cli/templates/codeyam-editor-claude.md +86 -5
  395. package/codeyam-cli/templates/codeyam-editor-codex.md +61 -0
  396. package/codeyam-cli/templates/codeyam-editor-gemini.md +59 -0
  397. package/codeyam-cli/templates/codeyam-editor-reference.md +216 -0
  398. package/codeyam-cli/templates/design-systems/clean-dashboard-design-system.md +255 -0
  399. package/codeyam-cli/templates/design-systems/editorial-design-system.md +267 -0
  400. package/codeyam-cli/templates/design-systems/mono-brutalist-design-system.md +256 -0
  401. package/codeyam-cli/templates/design-systems/neo-brutalist-design-system.md +294 -0
  402. package/codeyam-cli/templates/editor-step-hook.py +193 -56
  403. package/codeyam-cli/templates/expo-react-native/MOBILE_SETUP.md +204 -5
  404. package/codeyam-cli/templates/expo-react-native/README.md +41 -0
  405. package/codeyam-cli/templates/expo-react-native/__tests__/.gitkeep +0 -0
  406. package/codeyam-cli/templates/expo-react-native/app/_layout.tsx +6 -3
  407. package/codeyam-cli/templates/expo-react-native/app/index.tsx +36 -0
  408. package/codeyam-cli/templates/expo-react-native/app.json +11 -0
  409. package/codeyam-cli/templates/expo-react-native/babel.config.js +1 -0
  410. package/codeyam-cli/templates/expo-react-native/gitignore +2 -0
  411. package/codeyam-cli/templates/expo-react-native/global.css +7 -0
  412. package/codeyam-cli/templates/expo-react-native/lib/theme.ts +73 -0
  413. package/codeyam-cli/templates/expo-react-native/package.json +33 -16
  414. package/codeyam-cli/templates/expo-react-native/patches/expo-modules-autolinking+3.0.24.patch +29 -0
  415. package/codeyam-cli/templates/isolation-route/expo-router.tsx.template +54 -0
  416. package/codeyam-cli/templates/nextjs-prisma-sqlite/DATABASE.md +14 -0
  417. package/codeyam-cli/templates/nextjs-prisma-sqlite/README.md +53 -0
  418. package/codeyam-cli/templates/nextjs-prisma-sqlite/gitignore +1 -0
  419. package/codeyam-cli/templates/nextjs-prisma-sqlite/package.json +2 -1
  420. package/codeyam-cli/templates/nextjs-prisma-sqlite/seed-adapter.ts +88 -40
  421. package/codeyam-cli/templates/nextjs-prisma-supabase/README.md +52 -0
  422. package/codeyam-cli/templates/nextjs-prisma-supabase/package.json +2 -1
  423. package/codeyam-cli/templates/seed-adapters/supabase.ts +475 -0
  424. package/codeyam-cli/templates/skills/codeyam-dev-mode/SKILL.md +1 -1
  425. package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +109 -10
  426. package/package.json +2 -1
  427. package/packages/ai/src/lib/astScopes/methodSemantics.js +99 -0
  428. package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
  429. package/packages/ai/src/lib/astScopes/nodeToSource.js +16 -0
  430. package/packages/ai/src/lib/astScopes/nodeToSource.js.map +1 -1
  431. package/packages/ai/src/lib/astScopes/paths.js +12 -3
  432. package/packages/ai/src/lib/astScopes/paths.js.map +1 -1
  433. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +27 -10
  434. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  435. package/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.js +9 -2
  436. package/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.js.map +1 -1
  437. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +14 -4
  438. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  439. package/packages/analyze/index.js +1 -1
  440. package/packages/analyze/index.js.map +1 -1
  441. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +16 -2
  442. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  443. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +6 -26
  444. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  445. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js +3 -2
  446. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js.map +1 -1
  447. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +9 -7
  448. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
  449. package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js +14 -0
  450. package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js.map +1 -1
  451. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +44 -11
  452. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
  453. package/packages/analyze/src/lib/files/analyzeChange.js +1 -0
  454. package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
  455. package/packages/analyze/src/lib/files/analyzeInitial.js +1 -0
  456. package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
  457. package/packages/analyze/src/lib/files/analyzeNextRoute.js +5 -1
  458. package/packages/analyze/src/lib/files/analyzeNextRoute.js.map +1 -1
  459. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +120 -28
  460. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  461. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +1368 -1193
  462. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  463. package/packages/database/src/lib/kysely/tables/editorScenariosTable.js +84 -0
  464. package/packages/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -1
  465. package/packages/database/src/lib/loadAnalysis.js +7 -1
  466. package/packages/database/src/lib/loadAnalysis.js.map +1 -1
  467. package/packages/database/src/lib/loadEntities.js +0 -6
  468. package/packages/database/src/lib/loadEntities.js.map +1 -1
  469. package/packages/database/src/lib/loadEntity.js +5 -5
  470. package/packages/database/src/lib/loadEntity.js.map +1 -1
  471. package/packages/database/src/lib/updateCommitMetadata.js +0 -25
  472. package/packages/database/src/lib/updateCommitMetadata.js.map +1 -1
  473. package/packages/utils/src/lib/fs/rsyncCopy.js +22 -1
  474. package/packages/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  475. package/codeyam-cli/src/webserver/build/client/assets/CopyButton-BPXZwM4t.js +0 -1
  476. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeBadge-g3saevPb.js +0 -1
  477. package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-Bu6c6aDe.js +0 -1
  478. package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-DYFW3lDD.js +0 -25
  479. package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-DLeucoVX.js +0 -3
  480. package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-BED4B6sP.js +0 -1
  481. package/codeyam-cli/src/webserver/build/client/assets/Spinner-Bb5uFQ5V.js +0 -34
  482. package/codeyam-cli/src/webserver/build/client/assets/TruncatedFilePath-C8OKAR5x.js +0 -1
  483. package/codeyam-cli/src/webserver/build/client/assets/ViewportInspectBar-oAf2Kqsf.js +0 -1
  484. package/codeyam-cli/src/webserver/build/client/assets/chunk-JZWAC4HX-C4pqxYJB.js +0 -51
  485. package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-DcX-ZS3p.js +0 -1
  486. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-Csi0_PMl.js +0 -1
  487. package/codeyam-cli/src/webserver/build/client/assets/editor-pyT-NAuu.js +0 -10
  488. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-BLQMSKZa.js +0 -41
  489. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-C7YX6r3H.js +0 -6
  490. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-CF164ouH.js +0 -6
  491. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-p9hhkjJM.js +0 -6
  492. package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-cPo8LiG3.js +0 -1
  493. package/codeyam-cli/src/webserver/build/client/assets/files-BZrlFE1F.js +0 -1
  494. package/codeyam-cli/src/webserver/build/client/assets/git-DdZcvjGh.js +0 -1
  495. package/codeyam-cli/src/webserver/build/client/assets/globals-BkWJ_UNc.css +0 -1
  496. package/codeyam-cli/src/webserver/build/client/assets/labs-Zk7ryIM1.js +0 -1
  497. package/codeyam-cli/src/webserver/build/client/assets/manifest-753dd058.js +0 -1
  498. package/codeyam-cli/src/webserver/build/client/assets/memory-Bl2rpw8u.js +0 -96
  499. package/codeyam-cli/src/webserver/build/client/assets/root-B_X8HS1x.js +0 -67
  500. package/codeyam-cli/src/webserver/build/client/assets/settings-0OrEMU6J.js +0 -1
  501. package/codeyam-cli/src/webserver/build/client/assets/simulations-DWT-CvLy.js +0 -1
  502. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-CrAK28Bc.js +0 -1
  503. package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-C14nCb1q.js +0 -2
  504. package/codeyam-cli/src/webserver/build/client/assets/useReportContext-O-jkvSPx.js +0 -1
  505. package/codeyam-cli/src/webserver/build/client/assets/useToast-9FIWuYfK.js +0 -1
  506. package/codeyam-cli/src/webserver/build/server/assets/index-Bt1_4UUt.js +0 -1
  507. package/codeyam-cli/src/webserver/build/server/assets/server-build-1u5XIyLw.js +0 -416
  508. package/codeyam-cli/templates/expo-react-native/app/(tabs)/_layout.tsx +0 -33
  509. package/codeyam-cli/templates/expo-react-native/app/(tabs)/index.tsx +0 -12
  510. package/codeyam-cli/templates/expo-react-native/app/(tabs)/settings.tsx +0 -12
@@ -5,6 +5,7 @@ import path from 'path';
5
5
  import { getProjectRoot } from "../state.js";
6
6
  import { createMockStateManager, } from "../utils/editorMockState.js";
7
7
  import { computeEditorPorts } from "../utils/editorDevServer.js";
8
+ import { mockStateEventEmitter } from "./mockStateEvents.js";
8
9
  /**
9
10
  * Normalize a target URL by stripping trailing slashes for consistency.
10
11
  *
@@ -130,12 +131,58 @@ export const PREVIEW_HEALTH_SCRIPT = `<script data-codeyam-health>
130
131
  }).catch(function(){});
131
132
  }, 1000);
132
133
  });
134
+
135
+ // Network-idle detection: notify the parent editor when all initial
136
+ // fetch requests have completed, so it can show the preview after
137
+ // client-side data (API calls) has arrived — not just when the DOM loads.
138
+ var inflight = 0;
139
+ var settled = false;
140
+ var settleTimer = null;
141
+ var origFetch = window.fetch;
142
+ window.fetch = function() {
143
+ if (!settled) inflight++;
144
+ return origFetch.apply(this, arguments).then(function(resp) {
145
+ if (!settled) { inflight--; checkSettle(); }
146
+ return resp;
147
+ }, function(err) {
148
+ if (!settled) { inflight--; checkSettle(); }
149
+ throw err;
150
+ });
151
+ };
152
+ function checkSettle() {
153
+ if (inflight <= 0 && !settled) {
154
+ clearTimeout(settleTimer);
155
+ // Small delay to allow React to re-render with the fetched data
156
+ settleTimer = setTimeout(function() {
157
+ if (inflight <= 0) {
158
+ settled = true;
159
+ try {
160
+ window.parent.postMessage({ type: 'codeyam-preview-ready' }, '*');
161
+ } catch(e) {}
162
+ }
163
+ }, 100);
164
+ }
165
+ }
166
+ // Fallback: if no fetches happen (static page), settle after load
167
+ window.addEventListener('load', function() {
168
+ setTimeout(function() { checkSettle(); }, 200);
169
+ });
133
170
  })();
134
171
  </script>`;
135
172
  const CACHE_TTL_MS = 500;
136
173
  let scenarioCache = { data: null, timestamp: 0 };
137
174
  // Session config extracted from the active scenario — drives cookie injection
138
175
  let sessionConfig = undefined;
176
+ /** Session cookies from the seed adapter (e.g. Supabase auth tokens). */
177
+ let seedSessionCookies = undefined;
178
+ // localStorage config extracted from the active scenario — drives HTML injection
179
+ let localStorageConfig = null;
180
+ // Active scenario ID — used to gate localStorage seeding (only re-seed on switch)
181
+ let activeScenarioId = null;
182
+ // Prototype ID — used to gate a one-time localStorage.clear() when a new project is scaffolded
183
+ let currentPrototypeId = null;
184
+ // Current scenario type — 'application'/'user' for seed-based, 'component' for mock-based
185
+ let currentScenarioType = null;
139
186
  // Max body size to buffer for mock matching (10MB)
140
187
  const MAX_BODY_SIZE = 10 * 1024 * 1024;
141
188
  function getProxyState() {
@@ -189,6 +236,8 @@ function readScenarioData() {
189
236
  const active = JSON.parse(fs.readFileSync(activeScenarioPath, 'utf-8'));
190
237
  const scenarioId = active.scenarioId;
191
238
  if (!scenarioId) {
239
+ // No active scenario — but may have a prototypeId for localStorage clearing
240
+ currentPrototypeId = active.prototypeId || null;
192
241
  scenarioCache = { data: null, timestamp: now };
193
242
  return null;
194
243
  }
@@ -201,8 +250,14 @@ function readScenarioData() {
201
250
  const rawData = JSON.parse(fs.readFileSync(dataFilePath, 'utf-8'));
202
251
  // Extract session config for cookie injection
203
252
  sessionConfig = rawData.session || null;
253
+ // Extract seed adapter session cookies (e.g. Supabase auth)
254
+ seedSessionCookies = rawData.sessionCookies || undefined;
255
+ // Extract localStorage config for HTML injection
256
+ localStorageConfig = rawData.localStorage || null;
257
+ activeScenarioId = scenarioId;
204
258
  // Type-aware: for seed-based scenarios, only serve externalApis via proxy
205
259
  const scenarioType = active.type || rawData.type || null;
260
+ currentScenarioType = scenarioType;
206
261
  let mockData;
207
262
  if ((scenarioType === 'application' || scenarioType === 'user') &&
208
263
  rawData.seed) {
@@ -279,6 +334,10 @@ function forwardBufferedRequest(req, res, targetUrl, bodyBuffer) {
279
334
  // Remove accept-encoding so the dev server returns uncompressed responses.
280
335
  // The proxy injects a health script into HTML — this fails on compressed bodies.
281
336
  delete headers['accept-encoding'];
337
+ // Inject session cookies into the request so the dev server sees auth
338
+ // on the first request after a scenario switch (before the browser has
339
+ // stored them from Set-Cookie responses).
340
+ injectRequestCookies(headers);
282
341
  // Update content-length if we have the body buffer
283
342
  if (bodyBuffer) {
284
343
  headers['content-length'] = String(bodyBuffer.length);
@@ -292,6 +351,9 @@ function forwardBufferedRequest(req, res, targetUrl, bodyBuffer) {
292
351
  };
293
352
  const proxyReq = http.request(options, (proxyRes) => {
294
353
  const status = proxyRes.statusCode || 200;
354
+ if (status >= 300 && status < 400) {
355
+ console.log(`[editorProxy] Target redirect ${status} for ${req.method} ${req.url} → ${proxyRes.headers.location}`);
356
+ }
295
357
  if (status >= 400) {
296
358
  console.warn(`[editorProxy] Target returned ${status} for ${req.method} ${req.url}`);
297
359
  }
@@ -305,22 +367,54 @@ function forwardBufferedRequest(req, res, targetUrl, bodyBuffer) {
305
367
  proxyRes.on('data', (chunk) => chunks.push(chunk));
306
368
  proxyRes.on('end', () => {
307
369
  const body = Buffer.concat(chunks).toString('utf-8');
308
- const injected = injectHealthScript(body);
309
370
  delete headers['content-length'];
310
371
  delete headers['content-encoding'];
372
+ headers['cache-control'] = 'no-store, must-revalidate';
373
+ // Serve a friendly error page for 5xx responses instead of
374
+ // forwarding the raw error HTML (e.g. Next.js "Internal Server Error")
375
+ if (status >= 500) {
376
+ const errorPage = buildErrorPage(status, 'Internal Server Error', body);
377
+ res.writeHead(status, headers);
378
+ res.end(errorPage);
379
+ return;
380
+ }
381
+ const lsScript = buildLocalStorageScript(localStorageConfig, activeScenarioId || '', currentPrototypeId);
382
+ const injected = injectHealthScript(body, lsScript);
311
383
  res.writeHead(status, headers);
312
384
  res.end(injected);
313
385
  });
314
386
  return;
315
387
  }
388
+ // For 5xx responses without a content type or with text/plain,
389
+ // serve a friendly error page. These are typically broken dev servers
390
+ // (e.g. Next.js returning bare "Internal Server Error" with no headers).
391
+ // JSON API errors are left alone — they're legitimate responses.
392
+ if (status >= 500 && !contentType.includes('application/json')) {
393
+ const chunks = [];
394
+ proxyRes.on('data', (chunk) => chunks.push(chunk));
395
+ proxyRes.on('end', () => {
396
+ const body = Buffer.concat(chunks).toString('utf-8');
397
+ const errorPage = buildErrorPage(status, 'Internal Server Error', body);
398
+ res.writeHead(status, {
399
+ 'Content-Type': 'text/html',
400
+ 'Cache-Control': 'no-store',
401
+ });
402
+ res.end(errorPage);
403
+ });
404
+ return;
405
+ }
316
406
  res.writeHead(status, headers);
317
407
  proxyRes.pipe(res, { end: true });
318
408
  });
319
409
  proxyReq.on('error', (err) => {
320
410
  console.warn(`[editorProxy] Forward error for ${req.method} ${req.url}: ${err.message}`);
321
411
  if (!res.headersSent) {
322
- res.writeHead(502, { 'Content-Type': 'text/plain' });
323
- res.end('Bad Gateway — dev server unreachable');
412
+ const errorPage = buildErrorPage(502, 'Dev Server Unreachable', `The proxy could not connect to the dev server. It may be starting up, restarting, or crashed.\n\n${err.message}`);
413
+ res.writeHead(502, {
414
+ 'Content-Type': 'text/html',
415
+ 'Cache-Control': 'no-store',
416
+ });
417
+ res.end(errorPage);
324
418
  }
325
419
  });
326
420
  if (bodyBuffer && bodyBuffer.length > 0) {
@@ -341,18 +435,25 @@ function forwardRequest(req, res, targetUrl) {
341
435
  // Build headers, stripping accept-encoding so the dev server returns uncompressed
342
436
  // responses. The proxy injects a health script into HTML — this fails on compressed bodies.
343
437
  const { 'accept-encoding': _ae, ...forwardHeaders } = req.headers;
438
+ const reqHeaders = {
439
+ ...forwardHeaders,
440
+ host: `${target.hostname}:${target.port}`,
441
+ };
442
+ // Inject session cookies into the request so the dev server sees auth
443
+ // on the first request after a scenario switch.
444
+ injectRequestCookies(reqHeaders);
344
445
  const options = {
345
446
  hostname,
346
447
  port: target.port,
347
448
  path: req.url,
348
449
  method: req.method,
349
- headers: {
350
- ...forwardHeaders,
351
- host: `${target.hostname}:${target.port}`,
352
- },
450
+ headers: reqHeaders,
353
451
  };
354
452
  const proxyReq = http.request(options, (proxyRes) => {
355
453
  const status = proxyRes.statusCode || 200;
454
+ if (status >= 300 && status < 400) {
455
+ console.log(`[editorProxy] Target redirect ${status} for ${req.method} ${req.url} → ${proxyRes.headers.location}`);
456
+ }
356
457
  if (status >= 400) {
357
458
  console.warn(`[editorProxy] Target returned ${status} for ${req.method} ${req.url}`);
358
459
  }
@@ -367,24 +468,54 @@ function forwardRequest(req, res, targetUrl) {
367
468
  proxyRes.on('data', (chunk) => chunks.push(chunk));
368
469
  proxyRes.on('end', () => {
369
470
  const body = Buffer.concat(chunks).toString('utf-8');
370
- const injected = injectHealthScript(body);
371
- // Remove content-length since body size changed; use chunked transfer
372
471
  delete headers['content-length'];
373
- // Remove content-encoding since we're serving uncompressed
374
472
  delete headers['content-encoding'];
473
+ headers['cache-control'] = 'no-store, must-revalidate';
474
+ // Serve a friendly error page for 5xx responses instead of
475
+ // forwarding the raw error HTML (e.g. Next.js "Internal Server Error")
476
+ if (status >= 500) {
477
+ const errorPage = buildErrorPage(status, 'Internal Server Error', body);
478
+ res.writeHead(status, headers);
479
+ res.end(errorPage);
480
+ return;
481
+ }
482
+ const lsScript = buildLocalStorageScript(localStorageConfig, activeScenarioId || '', currentPrototypeId);
483
+ const injected = injectHealthScript(body, lsScript);
375
484
  res.writeHead(status, headers);
376
485
  res.end(injected);
377
486
  });
378
487
  return;
379
488
  }
489
+ // For 5xx responses without a content type or with text/plain,
490
+ // serve a friendly error page. These are typically broken dev servers
491
+ // (e.g. Next.js returning bare "Internal Server Error" with no headers).
492
+ // JSON API errors are left alone — they're legitimate responses.
493
+ if (status >= 500 && !contentType.includes('application/json')) {
494
+ const chunks = [];
495
+ proxyRes.on('data', (chunk) => chunks.push(chunk));
496
+ proxyRes.on('end', () => {
497
+ const body = Buffer.concat(chunks).toString('utf-8');
498
+ const errorPage = buildErrorPage(status, 'Internal Server Error', body);
499
+ res.writeHead(status, {
500
+ 'Content-Type': 'text/html',
501
+ 'Cache-Control': 'no-store',
502
+ });
503
+ res.end(errorPage);
504
+ });
505
+ return;
506
+ }
380
507
  res.writeHead(status, headers);
381
508
  proxyRes.pipe(res, { end: true });
382
509
  });
383
510
  proxyReq.on('error', (err) => {
384
511
  console.warn(`[editorProxy] Forward error for ${req.method} ${req.url}: ${err.message}`);
385
512
  if (!res.headersSent) {
386
- res.writeHead(502, { 'Content-Type': 'text/plain' });
387
- res.end('Bad Gateway — dev server unreachable');
513
+ const errorPage = buildErrorPage(502, 'Dev Server Unreachable', `The proxy could not connect to the dev server. It may be starting up, restarting, or crashed.\n\n${err.message}`);
514
+ res.writeHead(502, {
515
+ 'Content-Type': 'text/html',
516
+ 'Cache-Control': 'no-store',
517
+ });
518
+ res.end(errorPage);
388
519
  }
389
520
  });
390
521
  req.pipe(proxyReq, { end: true });
@@ -396,25 +527,94 @@ function forwardRequest(req, res, targetUrl) {
396
527
  * When sessionConfig is undefined (no scenario loaded yet), does nothing.
397
528
  */
398
529
  function injectSessionCookie(headers) {
399
- if (sessionConfig === undefined)
400
- return;
401
- let cookie;
402
- if (sessionConfig?.cookieValue) {
403
- cookie = `session-token=${sessionConfig.cookieValue}; Path=/; SameSite=Lax`;
530
+ const cookies = [];
531
+ // Dev auth cookie (built-in session-token)
532
+ if (sessionConfig !== undefined) {
533
+ if (sessionConfig?.cookieValue) {
534
+ cookies.push(`session-token=${sessionConfig.cookieValue}; Path=/; SameSite=Lax`);
535
+ }
536
+ else {
537
+ cookies.push(`session-token=; Path=/; Max-Age=0`);
538
+ }
404
539
  }
405
- else {
406
- // No session config clear any existing session cookie
407
- cookie = `session-token=; Path=/; Max-Age=0`;
540
+ // Seed adapter session cookies (e.g. Supabase auth tokens)
541
+ if (seedSessionCookies && seedSessionCookies.length > 0) {
542
+ for (const sc of seedSessionCookies) {
543
+ const cookiePath = sc.path || '/';
544
+ const sameSite = sc.sameSite || 'Lax';
545
+ cookies.push(`${sc.name}=${sc.value}; Path=${cookiePath}; SameSite=${sameSite}`);
546
+ }
408
547
  }
548
+ if (cookies.length === 0)
549
+ return;
409
550
  const existing = headers['set-cookie'];
410
551
  if (existing) {
411
552
  headers['set-cookie'] = [
412
553
  ...(Array.isArray(existing) ? existing : [existing]),
413
- cookie,
554
+ ...cookies,
414
555
  ];
415
556
  }
416
557
  else {
417
- headers['set-cookie'] = [cookie];
558
+ headers['set-cookie'] = cookies;
559
+ }
560
+ }
561
+ /**
562
+ * Get session cookies that should be injected into requests forwarded to the
563
+ * dev server. Returns an array of {name, value} pairs, or null if no session
564
+ * cookies are configured.
565
+ *
566
+ * This is the counterpart to `injectSessionCookie()` (which adds Set-Cookie
567
+ * to responses). Without request-side injection, the first request after a
568
+ * scenario switch has no cookies — the dev server's auth middleware sees no
569
+ * session and redirects to the login page before the browser ever receives
570
+ * the Set-Cookie response.
571
+ */
572
+ export function getRequestCookieInjection() {
573
+ const cookies = [];
574
+ if (sessionConfig?.cookieValue) {
575
+ cookies.push({ name: 'session-token', value: sessionConfig.cookieValue });
576
+ }
577
+ if (seedSessionCookies && seedSessionCookies.length > 0) {
578
+ for (const sc of seedSessionCookies) {
579
+ cookies.push({ name: sc.name, value: sc.value });
580
+ }
581
+ }
582
+ return cookies.length > 0 ? cookies : null;
583
+ }
584
+ /**
585
+ * Inject session cookies into the request's Cookie header before forwarding
586
+ * to the dev server. This ensures the dev server sees auth cookies on the
587
+ * very first request after a scenario switch (before the browser has stored
588
+ * them from Set-Cookie responses).
589
+ */
590
+ function injectRequestCookies(headers) {
591
+ const injection = getRequestCookieInjection();
592
+ if (!injection)
593
+ return;
594
+ // Parse existing cookies from the request
595
+ const existing = typeof headers.cookie === 'string' ? headers.cookie : '';
596
+ const existingPairs = existing
597
+ ? existing.split(';').map((s) => s.trim())
598
+ : [];
599
+ // Build a map of existing cookies for deduplication
600
+ const cookieMap = new Map();
601
+ for (const pair of existingPairs) {
602
+ const eqIdx = pair.indexOf('=');
603
+ if (eqIdx !== -1) {
604
+ cookieMap.set(pair.slice(0, eqIdx), pair.slice(eqIdx + 1));
605
+ }
606
+ }
607
+ // Override with injected cookies
608
+ for (const { name, value } of injection) {
609
+ cookieMap.set(name, value);
610
+ }
611
+ // Reassemble
612
+ const parts = [];
613
+ for (const [k, v] of cookieMap) {
614
+ parts.push(`${k}=${v}`);
615
+ }
616
+ if (parts.length > 0) {
617
+ headers.cookie = parts.join('; ');
418
618
  }
419
619
  }
420
620
  /**
@@ -424,17 +624,284 @@ export function getSessionConfig() {
424
624
  return sessionConfig;
425
625
  }
426
626
  /**
427
- * Inject the health-check script into an HTML response body.
627
+ * Get the current localStorage config (for testing and script generation).
628
+ */
629
+ export function getLocalStorageConfig() {
630
+ return localStorageConfig;
631
+ }
632
+ /**
633
+ * Get the active scenario ID (for testing and script generation).
634
+ */
635
+ export function getActiveScenarioId() {
636
+ return activeScenarioId;
637
+ }
638
+ /**
639
+ * Get the current prototype ID (for testing).
640
+ */
641
+ export function getCurrentPrototypeId() {
642
+ return currentPrototypeId;
643
+ }
644
+ /**
645
+ * Simple djb2 hash — fast, deterministic, good enough for cache busting.
646
+ * Not cryptographic — just detects when localStorage config content changes.
647
+ */
648
+ function simpleHash(str) {
649
+ let hash = 5381;
650
+ for (let i = 0; i < str.length; i++) {
651
+ hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;
652
+ }
653
+ return (hash >>> 0).toString(36);
654
+ }
655
+ /**
656
+ * Build a script tag that seeds localStorage with scenario data on first load.
657
+ * Gated by scenario ID — only seeds when the scenario changes, preserving
658
+ * interactive modifications across page reloads / HMR.
659
+ *
660
+ * Returns empty string if no localStorage config is provided.
661
+ */
662
+ export function buildLocalStorageScript(localStorageConfig, scenarioId, prototypeId) {
663
+ // null/undefined means no localStorage config at all — clean up keys
664
+ // that were set by a previous scenario so stale filter/sort state
665
+ // doesn't bleed through and hide data in the new scenario.
666
+ if (!localStorageConfig || typeof localStorageConfig !== 'object') {
667
+ // Always clean up previous scenario's keys, gated by scenarioId
668
+ // so it only runs once per switch (not on every HMR reload).
669
+ const guardValue = scenarioId ? `clear:${scenarioId}` : '';
670
+ if (prototypeId) {
671
+ return `<script data-codeyam-ls>
672
+ (function() {
673
+ if (localStorage.getItem('__codeyam_proto__') === ${JSON.stringify(prototypeId)}) return;
674
+ localStorage.clear();
675
+ localStorage.setItem('__codeyam_proto__', ${JSON.stringify(prototypeId)});
676
+ })();
677
+ </script>`;
678
+ }
679
+ if (scenarioId) {
680
+ // No prototypeId but we do have a scenarioId — clean up keys
681
+ // from the previous scenario without doing a full clear.
682
+ return `<script data-codeyam-ls>
683
+ (function() {
684
+ if (localStorage.getItem('__codeyam_ls_sid__') === ${JSON.stringify(guardValue)}) return;
685
+ var prev = JSON.parse(localStorage.getItem('__codeyam_ls_keys__') || '[]');
686
+ for (var i = 0; i < prev.length; i++) localStorage.removeItem(prev[i]);
687
+ localStorage.removeItem('__codeyam_ls_keys__');
688
+ localStorage.setItem('__codeyam_ls_sid__', ${JSON.stringify(guardValue)});
689
+ })();
690
+ </script>`;
691
+ }
692
+ return '';
693
+ }
694
+ // Even an empty object needs a cleanup script — switching from a scenario
695
+ // with localStorage data to one without must clear the previous keys.
696
+ const entries = Object.entries(localStorageConfig);
697
+ const keys = entries.map(([k]) => k);
698
+ // Build setItem calls — stringify non-string values
699
+ const setStatements = entries
700
+ .map(([key, value]) => {
701
+ const serialized = typeof value === 'string' ? value : JSON.stringify(value);
702
+ return `localStorage.setItem(${JSON.stringify(key)}, ${JSON.stringify(serialized)});`;
703
+ })
704
+ .join('\n');
705
+ // Guard value includes a content hash so re-registering a scenario with
706
+ // updated data (same ID, different content) busts the cache. Without this,
707
+ // the browser skips re-seeding because the scenario ID hasn't changed,
708
+ // causing stale data in the live preview while screenshots show fresh data.
709
+ const contentHash = simpleHash(JSON.stringify(localStorageConfig));
710
+ const guardValue = `${scenarioId}:${contentHash}`;
711
+ return (`<script data-codeyam-ls>
712
+ (function() {
713
+ if (localStorage.getItem('__codeyam_ls_sid__') === ${JSON.stringify(guardValue)}) return;
714
+ var prev = JSON.parse(localStorage.getItem('__codeyam_ls_keys__') || '[]');
715
+ for (var i = 0; i < prev.length; i++) localStorage.removeItem(prev[i]);
716
+ ${setStatements}
717
+ localStorage.setItem('__codeyam_ls_keys__', ${JSON.stringify(JSON.stringify(keys))});
718
+ localStorage.setItem('__codeyam_ls_sid__', ${JSON.stringify(guardValue)});
719
+ })();
720
+ </script>` + buildLocalStorageWatcherScript());
721
+ }
722
+ /**
723
+ * Build a script that watches for localStorage mutations and notifies the parent
724
+ * frame via postMessage. Also responds to `codeyam-get-localstorage` requests so
725
+ * the editor can read the current localStorage state when saving.
726
+ */
727
+ function buildLocalStorageWatcherScript() {
728
+ return `<script data-codeyam-ls-watcher>
729
+ (function() {
730
+ if (window.__codeyam_ls_watcher_installed__) return;
731
+ window.__codeyam_ls_watcher_installed__ = true;
732
+
733
+ var origSet = localStorage.setItem.bind(localStorage);
734
+ var origRemove = localStorage.removeItem.bind(localStorage);
735
+ var origClear = localStorage.clear.bind(localStorage);
736
+ window.__codeyam_orig_setItem__ = origSet;
737
+ window.__codeyam_orig_removeItem__ = origRemove;
738
+ window.__codeyam_orig_clear__ = origClear;
739
+
740
+ function isInternal(key) {
741
+ return typeof key === 'string' && key.indexOf('__codeyam_') === 0;
742
+ }
743
+
744
+ localStorage.setItem = function(key, value) {
745
+ origSet(key, value);
746
+ if (!isInternal(key) && window.parent !== window) {
747
+ window.parent.postMessage({ type: 'codeyam-localstorage-changed', action: 'set', key: key }, '*');
748
+ }
749
+ };
750
+
751
+ localStorage.removeItem = function(key) {
752
+ origRemove(key);
753
+ if (!isInternal(key) && window.parent !== window) {
754
+ window.parent.postMessage({ type: 'codeyam-localstorage-changed', action: 'remove', key: key }, '*');
755
+ }
756
+ };
757
+
758
+ localStorage.clear = function() {
759
+ origClear();
760
+ if (window.parent !== window) {
761
+ window.parent.postMessage({ type: 'codeyam-localstorage-changed', action: 'clear' }, '*');
762
+ }
763
+ };
764
+
765
+ window.addEventListener('message', function(event) {
766
+ if (event.data && event.data.type === 'codeyam-get-localstorage') {
767
+ var data = {};
768
+ for (var i = 0; i < localStorage.length; i++) {
769
+ var k = localStorage.key(i);
770
+ if (k && !isInternal(k)) {
771
+ data[k] = localStorage.getItem(k);
772
+ }
773
+ }
774
+ event.source.postMessage({ type: 'codeyam-localstorage-state', data: data }, '*');
775
+ }
776
+ });
777
+ })();
778
+ </script>`;
779
+ }
780
+ /**
781
+ * Inject the health-check script (and optional localStorage script) into an HTML response body.
428
782
  * Inserts before </head> if present, otherwise before </body>, otherwise appends.
783
+ * When a localStorageScript is provided, it's injected BEFORE the health script
784
+ * so localStorage is populated before the app loads.
429
785
  */
430
- export function injectHealthScript(html) {
786
+ export function injectHealthScript(html, localStorageScript) {
787
+ const scripts = (localStorageScript || '') + PREVIEW_HEALTH_SCRIPT;
431
788
  if (html.includes('</head>')) {
432
- return html.replace('</head>', PREVIEW_HEALTH_SCRIPT + '</head>');
789
+ return html.replace('</head>', scripts + '</head>');
433
790
  }
434
791
  if (html.includes('</body>')) {
435
- return html.replace('</body>', PREVIEW_HEALTH_SCRIPT + '</body>');
792
+ return html.replace('</body>', scripts + '</body>');
436
793
  }
437
- return html + PREVIEW_HEALTH_SCRIPT;
794
+ return html + scripts;
795
+ }
796
+ /**
797
+ * Escape HTML special characters to prevent XSS when embedding
798
+ * dev server error output into the error page.
799
+ */
800
+ export function escapeHtml(str) {
801
+ return str
802
+ .replace(/&/g, '&amp;')
803
+ .replace(/</g, '&lt;')
804
+ .replace(/>/g, '&gt;')
805
+ .replace(/"/g, '&quot;')
806
+ .replace(/'/g, '&#39;');
807
+ }
808
+ /**
809
+ * Build a self-contained HTML error page for display in the preview iframe.
810
+ *
811
+ * - Sends `codeyam-server-error` postMessage to the parent editor on load
812
+ * so the editor can auto-restart the dev server.
813
+ * - Includes a "Retry" button that sends `codeyam-server-error-retry`.
814
+ * - Does NOT send `codeyam-preview-ready` (so the editor doesn't
815
+ * mistake the error page for a successful load).
816
+ */
817
+ export function buildErrorPage(statusCode, title, detail) {
818
+ const escapedDetail = escapeHtml(detail);
819
+ const escapedTitle = escapeHtml(title);
820
+ return `<!DOCTYPE html>
821
+ <html lang="en">
822
+ <head>
823
+ <meta charset="utf-8" />
824
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
825
+ <title>${escapedTitle}</title>
826
+ <style>
827
+ * { margin: 0; padding: 0; box-sizing: border-box; }
828
+ body {
829
+ background: #1e1e1e;
830
+ color: #e0e0e0;
831
+ font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, sans-serif;
832
+ display: flex;
833
+ align-items: center;
834
+ justify-content: center;
835
+ min-height: 100vh;
836
+ padding: 24px;
837
+ }
838
+ .container {
839
+ max-width: 560px;
840
+ width: 100%;
841
+ text-align: center;
842
+ }
843
+ .status-code {
844
+ font-size: 48px;
845
+ font-weight: 600;
846
+ color: #f87171;
847
+ line-height: 1;
848
+ margin-bottom: 8px;
849
+ }
850
+ .title {
851
+ font-size: 18px;
852
+ font-weight: 500;
853
+ color: #f87171;
854
+ margin-bottom: 16px;
855
+ }
856
+ .detail {
857
+ background: #2a2a2a;
858
+ border: 1px solid #3a3a3a;
859
+ border-radius: 6px;
860
+ padding: 16px;
861
+ margin-bottom: 20px;
862
+ max-height: 240px;
863
+ overflow: auto;
864
+ text-align: left;
865
+ }
866
+ .detail pre {
867
+ font-family: 'IBM Plex Mono', monospace;
868
+ font-size: 12px;
869
+ color: #b0b0b0;
870
+ white-space: pre-wrap;
871
+ word-break: break-word;
872
+ }
873
+ .message {
874
+ font-size: 13px;
875
+ color: #888;
876
+ margin-bottom: 16px;
877
+ }
878
+ button {
879
+ background: #005c75;
880
+ color: white;
881
+ border: none;
882
+ border-radius: 4px;
883
+ padding: 8px 20px;
884
+ font-size: 14px;
885
+ font-weight: 500;
886
+ cursor: pointer;
887
+ transition: background 0.15s;
888
+ }
889
+ button:hover { background: #004d63; }
890
+ </style>
891
+ </head>
892
+ <body>
893
+ <div class="container">
894
+ <div class="status-code">${statusCode}</div>
895
+ <div class="title">${escapedTitle}</div>
896
+ <div class="detail"><pre>${escapedDetail}</pre></div>
897
+ <p class="message">Attempting to restart the dev server...</p>
898
+ <button onclick="window.parent.postMessage({type:'codeyam-server-error-retry'},'*')">Retry</button>
899
+ </div>
900
+ <script>
901
+ try { window.parent.postMessage({type:'codeyam-server-error',statusCode:${statusCode}},'*'); } catch(e) {}
902
+ </script>
903
+ </body>
904
+ </html>`;
438
905
  }
439
906
  /**
440
907
  * Handle POST /__codeyam__/preview-health — store health data in globalThis.
@@ -544,7 +1011,13 @@ function removeProxyConfig() {
544
1011
  * Supports all HTTP methods (GET, POST, PUT, DELETE, PATCH) with body buffering.
545
1012
  */
546
1013
  export async function startEditorProxy(options) {
547
- // Stop existing proxy first
1014
+ // If proxy is already running, reuse it (prevents second tab from killing first tab's proxy)
1015
+ const existing = getProxyState();
1016
+ if (existing) {
1017
+ console.log(`[editorProxy] Proxy already running on port ${existing.port} → ${existing.targetUrl}`);
1018
+ return { port: existing.port };
1019
+ }
1020
+ // Stop any leftover state (shouldn't happen, but defensive)
548
1021
  await stopEditorProxy();
549
1022
  let targetUrl = normalizeTargetUrl(options.targetUrl);
550
1023
  let port = options.port;
@@ -620,11 +1093,17 @@ export async function startEditorProxy(options) {
620
1093
  'Content-Type': 'application/json',
621
1094
  'Access-Control-Allow-Origin': '*',
622
1095
  'X-CodeYam-Proxy': 'scenario-data',
1096
+ 'Cache-Control': 'no-store',
623
1097
  });
624
1098
  res.end(match.body != null ? JSON.stringify(match.body) : '');
625
1099
  return;
626
1100
  }
627
1101
  // No mock match — forward with buffered body
1102
+ if ((currentScenarioType === 'application' ||
1103
+ currentScenarioType === 'user') &&
1104
+ pathname.startsWith('/api/')) {
1105
+ mockStateEventEmitter.emitDataMutationForwarded(method, pathname);
1106
+ }
628
1107
  forwardBufferedRequest(req, res, targetUrl, bodyBuffer);
629
1108
  return;
630
1109
  }
@@ -636,6 +1115,7 @@ export async function startEditorProxy(options) {
636
1115
  'Content-Type': 'application/json',
637
1116
  'Access-Control-Allow-Origin': '*',
638
1117
  'X-CodeYam-Proxy': 'scenario-data',
1118
+ 'Cache-Control': 'no-store',
639
1119
  });
640
1120
  res.end(match.body != null ? JSON.stringify(match.body) : '');
641
1121
  return;
@@ -707,6 +1187,10 @@ export async function stopEditorProxy() {
707
1187
  export function invalidateScenarioCache() {
708
1188
  scenarioCache = { data: null, timestamp: 0 };
709
1189
  sessionConfig = undefined;
1190
+ seedSessionCookies = undefined;
1191
+ localStorageConfig = null;
1192
+ activeScenarioId = null;
1193
+ currentPrototypeId = null;
710
1194
  }
711
1195
  /**
712
1196
  * Verify that the proxy can successfully forward a request to the target dev server.