@codeyam/codeyam-cli 0.1.0-staging.b147f46 → 0.1.0-staging.b49802d

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 (217) 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 +2 -2
  4. package/analyzer-template/packages/aws/package.json +5 -5
  5. package/analyzer-template/packages/database/package.json +1 -1
  6. package/analyzer-template/packages/database/src/lib/loadAnalysis.ts +7 -1
  7. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.d.ts.map +1 -1
  8. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js +7 -1
  9. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js.map +1 -1
  10. package/analyzer-template/project/runMultiScenarioServer.ts +26 -3
  11. package/background/src/lib/virtualized/project/runMultiScenarioServer.js +23 -3
  12. package/background/src/lib/virtualized/project/runMultiScenarioServer.js.map +1 -1
  13. package/codeyam-cli/src/commands/__tests__/editor.designSystem.test.js +30 -0
  14. package/codeyam-cli/src/commands/__tests__/editor.designSystem.test.js.map +1 -0
  15. package/codeyam-cli/src/commands/__tests__/editor.statePersistence.test.js +55 -0
  16. package/codeyam-cli/src/commands/__tests__/editor.statePersistence.test.js.map +1 -0
  17. package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js +39 -3
  18. package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js.map +1 -1
  19. package/codeyam-cli/src/commands/editor.js +773 -117
  20. package/codeyam-cli/src/commands/editor.js.map +1 -1
  21. package/codeyam-cli/src/commands/init.js +20 -0
  22. package/codeyam-cli/src/commands/init.js.map +1 -1
  23. package/codeyam-cli/src/data/designSystems.js +27 -0
  24. package/codeyam-cli/src/data/designSystems.js.map +1 -0
  25. package/codeyam-cli/src/data/techStacks.js +1 -1
  26. package/codeyam-cli/src/utils/__tests__/devServerState.test.js +93 -1
  27. package/codeyam-cli/src/utils/__tests__/devServerState.test.js.map +1 -1
  28. package/codeyam-cli/src/utils/__tests__/editorApi.test.js +44 -0
  29. package/codeyam-cli/src/utils/__tests__/editorApi.test.js.map +1 -1
  30. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +146 -0
  31. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
  32. package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js +98 -1
  33. package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js.map +1 -1
  34. package/codeyam-cli/src/utils/__tests__/editorRoadmap.test.js +1108 -0
  35. package/codeyam-cli/src/utils/__tests__/editorRoadmap.test.js.map +1 -0
  36. package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js +120 -0
  37. package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js.map +1 -1
  38. package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js +84 -0
  39. package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js.map +1 -1
  40. package/codeyam-cli/src/utils/__tests__/envFile.test.js +125 -0
  41. package/codeyam-cli/src/utils/__tests__/envFile.test.js.map +1 -0
  42. package/codeyam-cli/src/utils/__tests__/handoffContext.test.js +500 -0
  43. package/codeyam-cli/src/utils/__tests__/handoffContext.test.js.map +1 -0
  44. package/codeyam-cli/src/utils/__tests__/testRunner.test.js +0 -1
  45. package/codeyam-cli/src/utils/__tests__/testRunner.test.js.map +1 -1
  46. package/codeyam-cli/src/utils/__tests__/webappDetection.test.js +6 -0
  47. package/codeyam-cli/src/utils/__tests__/webappDetection.test.js.map +1 -1
  48. package/codeyam-cli/src/utils/designSystemShowcase.js +810 -0
  49. package/codeyam-cli/src/utils/designSystemShowcase.js.map +1 -0
  50. package/codeyam-cli/src/utils/devServerState.js +32 -0
  51. package/codeyam-cli/src/utils/devServerState.js.map +1 -1
  52. package/codeyam-cli/src/utils/editorApi.js +16 -0
  53. package/codeyam-cli/src/utils/editorApi.js.map +1 -1
  54. package/codeyam-cli/src/utils/editorAudit.js +28 -6
  55. package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
  56. package/codeyam-cli/src/utils/editorRoadmap.js +574 -0
  57. package/codeyam-cli/src/utils/editorRoadmap.js.map +1 -0
  58. package/codeyam-cli/src/utils/editorScenarioSwitch.js +27 -12
  59. package/codeyam-cli/src/utils/editorScenarioSwitch.js.map +1 -1
  60. package/codeyam-cli/src/utils/editorScenarios.js +11 -0
  61. package/codeyam-cli/src/utils/editorScenarios.js.map +1 -1
  62. package/codeyam-cli/src/utils/editorSeedAdapter.js +27 -14
  63. package/codeyam-cli/src/utils/editorSeedAdapter.js.map +1 -1
  64. package/codeyam-cli/src/utils/entityChangeStatus.server.js +15 -0
  65. package/codeyam-cli/src/utils/entityChangeStatus.server.js.map +1 -1
  66. package/codeyam-cli/src/utils/envFile.js +90 -0
  67. package/codeyam-cli/src/utils/envFile.js.map +1 -0
  68. package/codeyam-cli/src/utils/handoffContext.js +257 -0
  69. package/codeyam-cli/src/utils/handoffContext.js.map +1 -0
  70. package/codeyam-cli/src/utils/install-skills.js +36 -6
  71. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  72. package/codeyam-cli/src/utils/queue/__tests__/job.interactiveStart.test.js +159 -0
  73. package/codeyam-cli/src/utils/queue/__tests__/job.interactiveStart.test.js.map +1 -0
  74. package/codeyam-cli/src/utils/queue/job.js +9 -1
  75. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  76. package/codeyam-cli/src/utils/scenariosManifest.js +8 -2
  77. package/codeyam-cli/src/utils/scenariosManifest.js.map +1 -1
  78. package/codeyam-cli/src/utils/techStackConfig.js +38 -0
  79. package/codeyam-cli/src/utils/techStackConfig.js.map +1 -0
  80. package/codeyam-cli/src/utils/techStackConfig.test.js +85 -0
  81. package/codeyam-cli/src/utils/techStackConfig.test.js.map +1 -0
  82. package/codeyam-cli/src/utils/testResultCache.js +53 -0
  83. package/codeyam-cli/src/utils/testResultCache.js.map +1 -0
  84. package/codeyam-cli/src/utils/testResultCache.server.js +81 -0
  85. package/codeyam-cli/src/utils/testResultCache.server.js.map +1 -0
  86. package/codeyam-cli/src/utils/testResultCache.server.test.js +187 -0
  87. package/codeyam-cli/src/utils/testResultCache.server.test.js.map +1 -0
  88. package/codeyam-cli/src/utils/testResultCache.test.js +230 -0
  89. package/codeyam-cli/src/utils/testResultCache.test.js.map +1 -0
  90. package/codeyam-cli/src/utils/testRunner.js +1 -7
  91. package/codeyam-cli/src/utils/testRunner.js.map +1 -1
  92. package/codeyam-cli/src/utils/webappDetection.js +4 -2
  93. package/codeyam-cli/src/utils/webappDetection.js.map +1 -1
  94. package/codeyam-cli/src/webserver/__tests__/api.interactive-switch-scenario.test.js +99 -0
  95. package/codeyam-cli/src/webserver/__tests__/api.interactive-switch-scenario.test.js.map +1 -0
  96. package/codeyam-cli/src/webserver/__tests__/buildPtyEnv.test.js +119 -1
  97. package/codeyam-cli/src/webserver/__tests__/buildPtyEnv.test.js.map +1 -1
  98. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js +354 -1
  99. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js.map +1 -1
  100. package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js +32 -0
  101. package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js.map +1 -1
  102. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  103. package/codeyam-cli/src/webserver/app/routes/api.interactive-switch-scenario.js +34 -0
  104. package/codeyam-cli/src/webserver/app/routes/api.interactive-switch-scenario.js.map +1 -0
  105. package/codeyam-cli/src/webserver/build/client/assets/{CopyButton-CLe80MMu.js → CopyButton-DTBZZfSk.js} +1 -1
  106. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-Crt_KN_U.js → EntityItem-BxclONWq.js} +1 -1
  107. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-CD7lGABo.js → EntityTypeIcon-BsnEOJZ_.js} +1 -1
  108. package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-CgTNOhnu.js → InlineSpinner-ByaELMbv.js} +1 -1
  109. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CKeQT5Ty.js → InteractivePreview-6WjVfhxX.js} +2 -2
  110. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-D3s1MFkb.js → LibraryFunctionPreview-ChX-Hp7W.js} +1 -1
  111. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-CM5zg40N.js → LogViewer-C-9zQdXg.js} +1 -1
  112. package/codeyam-cli/src/webserver/build/client/assets/{MiniClaudeChat-CQENLSrF.js → MiniClaudeChat-Bs2_Oua4.js} +2 -2
  113. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-C2PLkej3.js → ReportIssueModal-DQsceHVv.js} +1 -1
  114. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-DanvyBPb.js → SafeScreenshot-DThcm_9M.js} +1 -1
  115. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DUMfcNVK.js → ScenarioViewer-Cl4oOA3A.js} +1 -1
  116. package/codeyam-cli/src/webserver/build/client/assets/Spinner-CIil5-gb.js +34 -0
  117. package/codeyam-cli/src/webserver/build/client/assets/{ViewportInspectBar-BA_Ry-rs.js → ViewportInspectBar-BqkA9zyZ.js} +1 -1
  118. package/codeyam-cli/src/webserver/build/client/assets/{_index-BAWd-Xjf.js → _index-DnOgyseQ.js} +1 -1
  119. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BOARiB-g.js → activity.(_tab)-DqM9hbNE.js} +1 -1
  120. package/codeyam-cli/src/webserver/build/client/assets/{addon-web-links-CHx25PAe.js → addon-web-links-C58dYPwR.js} +1 -1
  121. package/codeyam-cli/src/webserver/build/client/assets/{agent-transcripts-Bg3e7q4S.js → agent-transcripts-B8NCeOrm.js} +1 -1
  122. package/codeyam-cli/src/webserver/build/client/assets/api.editor-database-verify-l0sNRNKZ.js +1 -0
  123. package/codeyam-cli/src/webserver/build/client/assets/api.editor-github-verify-l0sNRNKZ.js +1 -0
  124. package/codeyam-cli/src/webserver/build/client/assets/api.editor-handoff-l0sNRNKZ.js +1 -0
  125. package/codeyam-cli/src/webserver/build/client/assets/api.editor-hosting-verify-l0sNRNKZ.js +1 -0
  126. package/codeyam-cli/src/webserver/build/client/assets/api.editor-roadmap-l0sNRNKZ.js +1 -0
  127. package/codeyam-cli/src/webserver/build/client/assets/api.editor-verify-routes-l0sNRNKZ.js +1 -0
  128. package/codeyam-cli/src/webserver/build/client/assets/api.interactive-switch-scenario-l0sNRNKZ.js +1 -0
  129. package/codeyam-cli/src/webserver/build/client/assets/{book-open-CL-lMgHh.js → book-open-BFSIqZgO.js} +1 -1
  130. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-GmAjGS9-.js → chevron-down-B9fDzFVh.js} +1 -1
  131. package/codeyam-cli/src/webserver/build/client/assets/chunk-UVKPFVEO-Bmq2apuh.js +43 -0
  132. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-DFcQkN5j.js → circle-check-DLPObLUx.js} +1 -1
  133. package/codeyam-cli/src/webserver/build/client/assets/{copy-C6iF61Xs.js → copy-DXEmO0TD.js} +1 -1
  134. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-4ImjHTVC.js → createLucideIcon-BwyFiRot.js} +1 -1
  135. package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-C8y4mmyv.js → dev.empty-iRhRIFlp.js} +1 -1
  136. package/codeyam-cli/src/webserver/build/client/assets/editor._tab-BZPBzV73.js +1 -0
  137. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-DhtVC4aI.js +161 -0
  138. package/codeyam-cli/src/webserver/build/client/assets/{editorPreview-CluPkvXJ.js → editorPreview-C6fEYHrh.js} +6 -6
  139. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-ByHz6rAQ.js → entity._sha._-pc-vc6wO.js} +1 -1
  140. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.dev-CmLO432x.js → entity._sha.scenarios._scenarioId.dev-C8AyYgYT.js} +1 -1
  141. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-Bz9sCUF_.js → entity._sha.scenarios._scenarioId.fullscreen-DziaVQX1.js} +1 -1
  142. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-DQM8E7L4.js → entity._sha_.create-scenario-BTcpgIpC.js} +1 -1
  143. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-CAoXLsQr.js → entity._sha_.edit._scenarioId-D_O_ajfZ.js} +1 -1
  144. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-SuW9syRS.js → entry.client-j1Vi0bco.js} +6 -6
  145. package/codeyam-cli/src/webserver/build/client/assets/{files-D-xGrg29.js → files-kuny2Q_s.js} +1 -1
  146. package/codeyam-cli/src/webserver/build/client/assets/{git-Bq_fbXP5.js → git-DgCZPMie.js} +1 -1
  147. package/codeyam-cli/src/webserver/build/client/assets/globals-L-aUIeux.css +1 -0
  148. package/codeyam-cli/src/webserver/build/client/assets/{index-Bp1l4hSv.js → index-BliGSSpl.js} +1 -1
  149. package/codeyam-cli/src/webserver/build/client/assets/{index-DE3jI_dv.js → index-SqjQKTdH.js} +1 -1
  150. package/codeyam-cli/src/webserver/build/client/assets/{index-CWV9XZiG.js → index-vyrZD2g4.js} +1 -1
  151. package/codeyam-cli/src/webserver/build/client/assets/{labs-B_IX45ih.js → labs-c3yLxSEp.js} +1 -1
  152. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-De-7qQ2u.js → loader-circle-D-q28GLF.js} +1 -1
  153. package/codeyam-cli/src/webserver/build/client/assets/manifest-79d0d81a.js +1 -0
  154. package/codeyam-cli/src/webserver/build/client/assets/{memory-Cx2xEx7s.js → memory-CEWIUC4t.js} +1 -1
  155. package/codeyam-cli/src/webserver/build/client/assets/{pause-CFxEKL1u.js → pause-BP6fitdh.js} +1 -1
  156. package/codeyam-cli/src/webserver/build/client/assets/{root-D2_tktnk.js → root-L2V0jea7.js} +4 -4
  157. package/codeyam-cli/src/webserver/build/client/assets/{search-BdBb5aqc.js → search-BooqacKS.js} +1 -1
  158. package/codeyam-cli/src/webserver/build/client/assets/{settings-DdE-Untf.js → settings-BM0nbryO.js} +1 -1
  159. package/codeyam-cli/src/webserver/build/client/assets/{simulations-DSCdE99u.js → simulations-ovy6FjRY.js} +1 -1
  160. package/codeyam-cli/src/webserver/build/client/assets/{terminal-CrplD4b1.js → terminal-DHemCJIs.js} +1 -1
  161. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-DqJ0j69l.js → triangle-alert-D87ekDl8.js} +1 -1
  162. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-DhXHbEjP.js → useCustomSizes-Dk0Tciqg.js} +1 -1
  163. package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-C8QvIe05.js +2 -0
  164. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-Cy5Qg_UR.js → useReportContext-jkCytuYz.js} +1 -1
  165. package/codeyam-cli/src/webserver/build/client/assets/{useToast-5HR2j9ZE.js → useToast-BgqkixU9.js} +1 -1
  166. package/codeyam-cli/src/webserver/build/server/assets/{analysisRunner-By5slFjw.js → analysisRunner-QgInFGdU.js} +1 -1
  167. package/codeyam-cli/src/webserver/build/server/assets/{index-DXaOwBnm.js → index-zblh9auj.js} +1 -1
  168. package/codeyam-cli/src/webserver/build/server/assets/init-DaE0CBjk.js +14 -0
  169. package/codeyam-cli/src/webserver/build/server/assets/server-build-CNvgz1cC.js +853 -0
  170. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  171. package/codeyam-cli/src/webserver/build-info.json +5 -5
  172. package/codeyam-cli/src/webserver/editorProxy.js +255 -20
  173. package/codeyam-cli/src/webserver/editorProxy.js.map +1 -1
  174. package/codeyam-cli/src/webserver/idleDetector.js +12 -3
  175. package/codeyam-cli/src/webserver/idleDetector.js.map +1 -1
  176. package/codeyam-cli/src/webserver/server.js +67 -0
  177. package/codeyam-cli/src/webserver/server.js.map +1 -1
  178. package/codeyam-cli/src/webserver/terminalServer.js +106 -14
  179. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
  180. package/codeyam-cli/templates/codeyam-editor-codex.md +61 -0
  181. package/codeyam-cli/templates/codeyam-editor-gemini.md +59 -0
  182. package/codeyam-cli/templates/design-systems/clean-dashboard-design-system.md +255 -0
  183. package/codeyam-cli/templates/design-systems/editorial-design-system.md +267 -0
  184. package/codeyam-cli/templates/design-systems/mono-brutalist-design-system.md +256 -0
  185. package/codeyam-cli/templates/design-systems/neo-brutalist-design-system.md +294 -0
  186. package/codeyam-cli/templates/editor-step-hook.py +4 -4
  187. package/codeyam-cli/templates/expo-react-native/MOBILE_SETUP.md +204 -5
  188. package/codeyam-cli/templates/expo-react-native/__tests__/.gitkeep +0 -0
  189. package/codeyam-cli/templates/expo-react-native/app/_layout.tsx +6 -3
  190. package/codeyam-cli/templates/expo-react-native/app/index.tsx +36 -0
  191. package/codeyam-cli/templates/expo-react-native/app.json +11 -0
  192. package/codeyam-cli/templates/expo-react-native/babel.config.js +1 -0
  193. package/codeyam-cli/templates/expo-react-native/gitignore +2 -0
  194. package/codeyam-cli/templates/expo-react-native/global.css +7 -0
  195. package/codeyam-cli/templates/expo-react-native/lib/theme.ts +73 -0
  196. package/codeyam-cli/templates/expo-react-native/package.json +32 -16
  197. package/codeyam-cli/templates/expo-react-native/patches/expo-modules-autolinking+3.0.24.patch +29 -0
  198. package/codeyam-cli/templates/isolation-route/expo-router.tsx.template +54 -0
  199. package/codeyam-cli/templates/nextjs-prisma-sqlite/gitignore +1 -0
  200. package/codeyam-cli/templates/nextjs-prisma-sqlite/seed-adapter.ts +10 -5
  201. package/codeyam-cli/templates/seed-adapters/supabase.ts +271 -78
  202. package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +15 -0
  203. package/package.json +1 -1
  204. package/packages/database/src/lib/loadAnalysis.js +7 -1
  205. package/packages/database/src/lib/loadAnalysis.js.map +1 -1
  206. package/codeyam-cli/src/webserver/build/client/assets/Spinner-D0LgAaSa.js +0 -34
  207. package/codeyam-cli/src/webserver/build/client/assets/chunk-JZWAC4HX-BAdwhyCx.js +0 -43
  208. package/codeyam-cli/src/webserver/build/client/assets/editor._tab-Gbk_i5Js.js +0 -1
  209. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-DMv5ESGo.js +0 -96
  210. package/codeyam-cli/src/webserver/build/client/assets/globals-oyPmV37k.css +0 -1
  211. package/codeyam-cli/src/webserver/build/client/assets/manifest-1a45e154.js +0 -1
  212. package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-BNd5hYuW.js +0 -2
  213. package/codeyam-cli/src/webserver/build/server/assets/init-CLG1LjQM.js +0 -10
  214. package/codeyam-cli/src/webserver/build/server/assets/server-build-NZmUqQv6.js +0 -688
  215. package/codeyam-cli/templates/expo-react-native/app/(tabs)/_layout.tsx +0 -33
  216. package/codeyam-cli/templates/expo-react-native/app/(tabs)/index.tsx +0 -12
  217. package/codeyam-cli/templates/expo-react-native/app/(tabs)/settings.tsx +0 -12
@@ -10,27 +10,39 @@
10
10
  * "tableName": [{ "column": "value", ... }, ...],
11
11
  * "_auth": { // optional
12
12
  * "email": "alice@example.com",
13
- * "password": "test123"
13
+ * "password": "test123" // optional — default used if omitted
14
14
  * }
15
15
  * }
16
16
  *
17
17
  * When _auth is present, the adapter:
18
18
  * 1. Creates the user if they don't exist (auto-confirms email)
19
- * 2. Signs in with signInWithPassword to get a valid session
20
- * 3. Writes session cookies to .codeyam/tmp/seed-session.json
19
+ * 2. Builds a synthetic JWT with far-future expiry (no real sign-in needed)
20
+ * 3. Writes session cookies + auth mocks to .codeyam/tmp/seed-session.json
21
21
  * so the CodeYam proxy can inject them into the browser
22
22
  *
23
+ * The password field is optional — if omitted, a default dev password is used.
24
+ * No real JWTs are stored; the preload module intercepts all auth API calls.
25
+ *
26
+ * Data operations use direct PostgreSQL (pg) for speed — TRUNCATE CASCADE
27
+ * and batched INSERT are ~2x faster than individual PostgREST HTTP calls.
28
+ *
23
29
  * Requirements:
30
+ * - DATABASE_URL env var with a PostgreSQL connection string (session pooler recommended)
24
31
  * - A Supabase project URL (https://<ref>.supabase.co) in any env var
25
32
  * - A secret key (sb_secret_... or legacy eyJ... service_role JWT) in any env var
26
33
  *
27
- * The adapter scans ALL env vars by value pattern no specific naming required.
34
+ * The adapter scans ALL env vars by value pattern for Supabase URL and secret key —
35
+ * no specific naming required. DATABASE_URL must be set explicitly.
28
36
  */
29
37
 
30
38
  import { createClient } from '@supabase/supabase-js';
39
+ import { Prisma } from '@prisma/client';
40
+ import pg from 'pg';
31
41
  import * as fs from 'fs';
32
42
  import * as path from 'path';
33
43
 
44
+ const { Client } = pg;
45
+
34
46
  /**
35
47
  * Scan all env vars for values matching a pattern.
36
48
  * Returns ALL unique matches (not just the first) so callers can disambiguate.
@@ -65,7 +77,6 @@ const supabaseUrl = findAllEnvByPattern(
65
77
 
66
78
  // New-format keys are unambiguous by prefix
67
79
  const newSecretKey = findAllEnvByPattern(/^sb_secret_/)[0];
68
- const newAnonKey = findAllEnvByPattern(/^sb_publishable_/)[0];
69
80
 
70
81
  // Legacy JWT keys — disambiguate by decoding the role claim
71
82
  const legacyJwts = findAllEnvByPattern(
@@ -74,10 +85,8 @@ const legacyJwts = findAllEnvByPattern(
74
85
  const legacyServiceRole = legacyJwts.find(
75
86
  (jwt) => getJwtRole(jwt) === 'service_role',
76
87
  );
77
- const legacyAnon = legacyJwts.find((jwt) => getJwtRole(jwt) === 'anon');
78
88
 
79
89
  const secretKey = newSecretKey || legacyServiceRole;
80
- const anonKey = newAnonKey || legacyAnon;
81
90
 
82
91
  if (!supabaseUrl || !secretKey) {
83
92
  console.error(
@@ -92,7 +101,17 @@ if (!supabaseUrl || !secretKey) {
92
101
  process.exit(1);
93
102
  }
94
103
 
95
- // Admin client for user management (uses secret key to bypass RLS)
104
+ // DATABASE_URL for direct PostgreSQL access (session pooler recommended for speed)
105
+ const databaseUrl = process.env.DATABASE_URL;
106
+ if (!databaseUrl || !databaseUrl.startsWith('postgresql://')) {
107
+ console.error('DATABASE_URL must be set to a PostgreSQL connection string.');
108
+ console.error(
109
+ 'Use the session pooler connection string (port 5432) from your Supabase dashboard.',
110
+ );
111
+ process.exit(1);
112
+ }
113
+
114
+ // Admin client for user management only (uses secret key to bypass RLS)
96
115
  const supabase = createClient(supabaseUrl, secretKey, {
97
116
  auth: { autoRefreshToken: false, persistSession: false },
98
117
  });
@@ -108,53 +127,213 @@ function getProjectRef(): string {
108
127
  }
109
128
  }
110
129
 
130
+ /**
131
+ * Build a mapping from lowercased seed-data keys to actual PostgreSQL table names.
132
+ * Prisma creates tables with the model name (PascalCase) unless @@map is used.
133
+ * PostgreSQL requires the exact table name, so we need this translation.
134
+ */
135
+ function buildTableNameMap(): Record<string, string> {
136
+ const map: Record<string, string> = {};
137
+ for (const model of Prisma.dmmf.datamodel.models) {
138
+ // dbName is set when @@map is used, otherwise null → use model name
139
+ const dbName = (model as any).dbName || model.name;
140
+ // Map lowercased model name → actual table name
141
+ const lowered = model.name.charAt(0).toLowerCase() + model.name.slice(1);
142
+ map[lowered] = dbName;
143
+ map[model.name] = dbName; // Also map PascalCase for safety
144
+ }
145
+ return map;
146
+ }
147
+
148
+ /**
149
+ * Build column name mapping from Prisma field names to database column names.
150
+ * Prisma uses camelCase field names but generates snake_case columns unless @map is used.
151
+ */
152
+ function buildColumnMap(tableName: string): Record<string, string> {
153
+ const map: Record<string, string> = {};
154
+ for (const model of Prisma.dmmf.datamodel.models) {
155
+ const dbName = (model as any).dbName || model.name;
156
+ if (dbName !== tableName) continue;
157
+ for (const field of model.fields) {
158
+ if (field.kind === 'object') continue; // Skip relation fields
159
+ const colName = (field as any).dbName || field.name;
160
+ map[field.name] = colName;
161
+ }
162
+ break;
163
+ }
164
+ return map;
165
+ }
166
+
111
167
  async function seedTables(seed: Record<string, unknown[]>) {
112
- const tableNames = Object.keys(seed);
113
- if (tableNames.length === 0) return;
114
-
115
- console.log(`Seeding tables: ${tableNames.join(', ')}`);
116
-
117
- // Wipe tables in reverse order (to respect foreign keys)
118
- for (const table of [...tableNames].reverse()) {
119
- const { error } = await supabase.from(table).delete().gte('id', 0);
120
- if (error) {
121
- const { error: error2 } = await supabase
122
- .from(table)
123
- .delete()
124
- .not('id', 'is', null);
125
- if (error2) {
126
- console.warn(` Could not clear ${table}: ${error2.message}`);
127
- } else {
128
- console.log(` Cleared ${table}`);
168
+ if (Object.keys(seed).length === 0) return;
169
+
170
+ const tableMap = buildTableNameMap();
171
+
172
+ // Discover ALL models from the Prisma schema — not just the tables in the seed data.
173
+ // This ensures FK-dependent tables are cleared even when the seed only contains
174
+ // the parent table's data.
175
+ const allTables = Prisma.dmmf.datamodel.models.map(
176
+ (m) => (m as any).dbName || m.name,
177
+ );
178
+
179
+ console.log(
180
+ `Clearing ${allTables.length} tables, seeding: ${Object.keys(seed).join(', ')}`,
181
+ );
182
+
183
+ const client = new Client({
184
+ connectionString: databaseUrl,
185
+ ssl: { rejectUnauthorized: false },
186
+ });
187
+ await client.connect();
188
+
189
+ try {
190
+ // TRUNCATE all tables in one statement — CASCADE handles FK dependencies
191
+ // automatically, so table order doesn't matter. Much faster than
192
+ // individual DELETE FROM queries via PostgREST.
193
+ const quoted = allTables.map((t) => `"${t}"`).join(', ');
194
+ await client.query(`TRUNCATE ${quoted} CASCADE`);
195
+ console.log(` Cleared ${allTables.length} tables`);
196
+
197
+ // Reset auto-increment sequences so IDs start from 1 on each scenario switch.
198
+ // Without this, IDs keep climbing and hardcoded URLs like /drinks/1 break.
199
+ for (const table of allTables) {
200
+ try {
201
+ await client.query(
202
+ `SELECT setval(pg_get_serial_sequence('"${table}"', 'id'), 1, false)`,
203
+ );
204
+ } catch {
205
+ // Table may not have an 'id' serial column — skip
129
206
  }
130
- } else {
131
- console.log(` Cleared ${table}`);
132
207
  }
208
+
209
+ // Insert seed data using batched INSERT for speed
210
+ for (const [seedKey, rows] of Object.entries(seed)) {
211
+ if (!Array.isArray(rows) || rows.length === 0) continue;
212
+ const table = tableMap[seedKey] || seedKey;
213
+ const columnMap = buildColumnMap(table);
214
+
215
+ // Get column names from the first row's keys, mapped to DB column names
216
+ const fieldNames = Object.keys(rows[0] as Record<string, unknown>);
217
+ const dbColumns = fieldNames.map((f) => columnMap[f] || f);
218
+ const quotedCols = dbColumns.map((c) => `"${c}"`).join(', ');
219
+
220
+ // Build parameterized VALUES clause for all rows at once
221
+ const params: unknown[] = [];
222
+ const valueClauses: string[] = [];
223
+ for (let i = 0; i < rows.length; i++) {
224
+ const row = rows[i] as Record<string, unknown>;
225
+ const placeholders: string[] = [];
226
+ for (const field of fieldNames) {
227
+ params.push(row[field]);
228
+ placeholders.push(`$${params.length}`);
229
+ }
230
+ valueClauses.push(`(${placeholders.join(', ')})`);
231
+ }
232
+
233
+ await client.query(
234
+ `INSERT INTO "${table}" (${quotedCols}) VALUES ${valueClauses.join(', ')}`,
235
+ params,
236
+ );
237
+ console.log(` Seeded ${rows.length} rows into ${table}`);
238
+ }
239
+ } finally {
240
+ await client.end();
133
241
  }
242
+ }
134
243
 
135
- // Insert seed data
136
- for (const [table, rows] of Object.entries(seed)) {
137
- if (!Array.isArray(rows) || rows.length === 0) continue;
138
- const { error } = await supabase.from(table).insert(rows);
139
- if (error) {
140
- console.error(` Failed to seed ${table}: ${error.message}`);
141
- process.exit(1);
244
+ /**
245
+ * Export mode: dump current database state to a JSON file.
246
+ * Used by CodeYam to save interactive changes back to scenario seed data.
247
+ *
248
+ * Usage: npx tsx .codeyam/seed-adapter.ts --export <output-path.json>
249
+ */
250
+ async function exportData(outputPath: string) {
251
+ const tableMap = buildTableNameMap();
252
+ const modelNames = Prisma.dmmf.datamodel.models.map((m) => m.name);
253
+
254
+ const client = new Client({
255
+ connectionString: databaseUrl,
256
+ ssl: { rejectUnauthorized: false },
257
+ });
258
+ await client.connect();
259
+
260
+ try {
261
+ const seed: Record<string, unknown[]> = {};
262
+ for (const model of modelNames) {
263
+ const camelCase = model.charAt(0).toLowerCase() + model.slice(1);
264
+ const table = tableMap[camelCase] || model;
265
+ try {
266
+ const result = await client.query(`SELECT * FROM "${table}"`);
267
+ if (result.rows.length > 0) {
268
+ seed[camelCase] = result.rows;
269
+ }
270
+ } catch {
271
+ // Skip tables that can't be queried
272
+ }
142
273
  }
143
- console.log(` Seeded ${rows.length} rows into ${table}`);
274
+
275
+ fs.writeFileSync(outputPath, JSON.stringify(seed, null, 2));
276
+ console.log(`Exported ${Object.keys(seed).length} tables`);
277
+ } finally {
278
+ await client.end();
144
279
  }
145
280
  }
146
281
 
147
282
  /**
148
- * Handle auth: create user, sign in, write session cookies.
283
+ * Build a minimal JWT with a far-future expiry.
284
+ * The signature is fake — it doesn't matter because the CodeYam preload module
285
+ * intercepts the Supabase auth validation endpoint and returns mock data.
286
+ */
287
+ function buildFakeJwt(userId: string, email: string): string {
288
+ const header = { alg: 'HS256', typ: 'JWT' };
289
+ const payload = {
290
+ sub: userId,
291
+ email,
292
+ role: 'authenticated',
293
+ aud: 'authenticated',
294
+ exp: 9999999999,
295
+ iat: Math.floor(Date.now() / 1000),
296
+ };
297
+ const encode = (obj: object) =>
298
+ Buffer.from(JSON.stringify(obj)).toString('base64url');
299
+ return `${encode(header)}.${encode(payload)}.codeyam-mock-signature`;
300
+ }
301
+
302
+ /**
303
+ * Build a Supabase user response object matching the /auth/v1/user endpoint format.
304
+ */
305
+ function buildUserResponse(user: { id: string; email?: string }) {
306
+ return {
307
+ id: user.id,
308
+ aud: 'authenticated',
309
+ role: 'authenticated',
310
+ email: user.email || '',
311
+ email_confirmed_at: new Date().toISOString(),
312
+ app_metadata: { provider: 'email', providers: ['email'] },
313
+ user_metadata: {},
314
+ created_at: new Date().toISOString(),
315
+ };
316
+ }
317
+
318
+ const DEFAULT_AUTH_PASSWORD = 'codeyam-dev-password-123!';
319
+
320
+ /**
321
+ * Handle auth: create user, build synthetic session, write session cookies.
149
322
  * Returns the user ID so callers can replace __AUTH_USER_ID__ placeholders in seed data.
323
+ *
324
+ * No real sign-in is performed — the session cookie uses a synthetic JWT with
325
+ * far-future expiry, and externalApis mocks intercept all Supabase auth API calls.
326
+ * This avoids storing real tokens (security risk + expiration) in scenario files.
150
327
  */
151
328
  async function handleAuth(auth: {
152
329
  email: string;
153
- password: string;
330
+ password?: string;
154
331
  }): Promise<string> {
155
- const { email, password } = auth;
332
+ const email = auth.email;
333
+ const password = auth.password || DEFAULT_AUTH_PASSWORD;
156
334
 
157
- // Create user if they don't exist (auto-confirm email so sign-in works)
335
+ // Create user if they don't exist (auto-confirm email)
336
+ // We still need the auth.users row for PostgREST FK relationships.
158
337
  const { data: createData, error: createError } =
159
338
  await supabase.auth.admin.createUser({
160
339
  email,
@@ -162,72 +341,79 @@ async function handleAuth(auth: {
162
341
  email_confirm: true,
163
342
  });
164
343
 
344
+ let userId: string;
345
+
165
346
  if (createError) {
166
347
  if (createError.message.includes('already been registered')) {
167
- // User exists — update their password so sign-in works even if the
168
- // scenario specifies a different password than a previous run.
348
+ // User exists — look up their ID
169
349
  const { data: listData } = await supabase.auth.admin.listUsers();
170
350
  const existingUser = listData?.users?.find((u) => u.email === email);
171
351
  if (existingUser) {
172
- await supabase.auth.admin.updateUserById(existingUser.id, {
173
- password,
174
- });
175
- console.log(` Updated password for existing user ${email}`);
352
+ userId = existingUser.id;
353
+ console.log(` Found existing user ${email} (user: ${userId})`);
354
+ } else {
355
+ console.error(
356
+ ` User ${email} reported as registered but not found in listUsers`,
357
+ );
358
+ process.exit(1);
176
359
  }
177
360
  } else {
178
361
  console.error(` Failed to create auth user: ${createError.message}`);
179
362
  process.exit(1);
180
363
  }
364
+ } else {
365
+ userId = createData!.user.id;
366
+ console.log(` Created user ${email} (user: ${userId})`);
181
367
  }
182
368
 
183
- // Sign in to get a valid session
184
- // Use a separate client with the publishable/anon key for sign-in (if available)
185
- const signInClient =
186
- anonKey && anonKey !== secretKey
187
- ? createClient(supabaseUrl!, anonKey, {
188
- auth: { autoRefreshToken: false, persistSession: false },
189
- })
190
- : supabase;
191
-
192
- const { data: signInData, error: signInError } =
193
- await signInClient.auth.signInWithPassword({ email, password });
194
-
195
- if (signInError || !signInData.session) {
196
- console.error(
197
- ` Failed to sign in as ${email}: ${signInError?.message || 'no session returned'}`,
198
- );
199
- process.exit(1);
200
- }
201
-
202
- const userId = signInData.user.id;
203
- console.log(` Signed in as ${email} (user: ${userId})`);
369
+ // Build synthetic JWT and mock responses — no real sign-in needed.
370
+ // The preload module intercepts server-side getUser() calls so Next.js
371
+ // middleware returns the mock user without hitting real Supabase.
372
+ const fakeJwt = buildFakeJwt(userId!, email);
373
+ const userResponse = buildUserResponse({ id: userId!, email });
204
374
 
205
- // Write session cookies for the proxy to inject
206
375
  const projectRef = getProjectRef();
207
376
  const sessionOutput = {
208
377
  cookies: [
209
378
  {
210
379
  name: `sb-${projectRef}-auth-token`,
211
380
  value: JSON.stringify({
212
- access_token: signInData.session.access_token,
213
- refresh_token: signInData.session.refresh_token,
381
+ access_token: fakeJwt,
382
+ refresh_token: 'codeyam-mock-refresh-token',
214
383
  token_type: 'bearer',
215
- expires_in: signInData.session.expires_in,
216
- expires_at: signInData.session.expires_at,
384
+ expires_in: 315360000,
385
+ expires_at: 9999999999,
217
386
  }),
218
387
  path: '/',
219
388
  sameSite: 'Lax' as const,
220
389
  },
221
390
  ],
391
+ externalApis: {
392
+ [`${supabaseUrl}/auth/v1/user`]: {
393
+ body: userResponse,
394
+ status: 200,
395
+ },
396
+ [`${supabaseUrl}/auth/v1/token`]: {
397
+ body: {
398
+ access_token: fakeJwt,
399
+ token_type: 'bearer',
400
+ expires_in: 315360000,
401
+ expires_at: 9999999999,
402
+ refresh_token: 'codeyam-mock-refresh-token',
403
+ user: userResponse,
404
+ },
405
+ status: 200,
406
+ },
407
+ },
222
408
  };
223
409
 
224
410
  const outputDir = path.join(process.cwd(), '.codeyam', 'tmp');
225
411
  fs.mkdirSync(outputDir, { recursive: true });
226
412
  const outputPath = path.join(outputDir, 'seed-session.json');
227
413
  fs.writeFileSync(outputPath, JSON.stringify(sessionOutput, null, 2));
228
- console.log(` Session cookies written to ${outputPath}`);
414
+ console.log(` Session cookies + auth mocks written to ${outputPath}`);
229
415
 
230
- return userId;
416
+ return userId!;
231
417
  }
232
418
 
233
419
  /**
@@ -266,7 +452,7 @@ async function main() {
266
452
  // in seed data (e.g. for user_id foreign key columns with Supabase RLS)
267
453
  if (auth) {
268
454
  const userId = await handleAuth(
269
- auth as { email: string; password: string },
455
+ auth as { email: string; password?: string },
270
456
  );
271
457
  seed = replaceAuthPlaceholders(seed, userId);
272
458
  }
@@ -276,7 +462,14 @@ async function main() {
276
462
  console.log('Seed complete');
277
463
  }
278
464
 
279
- main().catch((e) => {
280
- console.error('Seed adapter error:', e);
281
- process.exit(1);
282
- });
465
+ if (process.argv[2] === '--export') {
466
+ exportData(process.argv[3]).catch((e) => {
467
+ console.error('Seed adapter export error:', e);
468
+ process.exit(1);
469
+ });
470
+ } else {
471
+ main().catch((e) => {
472
+ console.error('Seed adapter error:', e);
473
+ process.exit(1);
474
+ });
475
+ }
@@ -175,6 +175,21 @@ Isolation routes are committed to git (not gitignored). They are protected by a
175
175
 
176
176
  When a collaborator clones the repo and runs `codeyam editor`, scenarios are auto-imported from `scenarios-manifest.json`. Run `codeyam editor sync` to manually re-sync after pulling new changes.
177
177
 
178
+ ## Expo / React Native Projects
179
+
180
+ When working with an Expo project (tech stack `expo-react-native`):
181
+
182
+ - Use `<View>`, `<Text>`, `<ScrollView>`, `<Pressable>` from `react-native` — **never use HTML elements** (`<div>`, `<span>`, `<h1>`, etc.)
183
+ - Do NOT use `'use client'` — this is a Next.js directive that has no meaning in Expo
184
+ - Do NOT import from `next/navigation`, `next/router`, or any `next/*` package
185
+ - Use `expo-router` for navigation: `useRouter()`, `useLocalSearchParams()`, `<Link>`
186
+ - Use `@/lib/theme` for all design tokens — not CSS custom properties (`var(--token)` does not work in React Native)
187
+ - AsyncStorage maps to localStorage on web — CodeYam's `localStorage` injection in scenarios works automatically
188
+ - Test with `npx jest`, not `npx vitest`
189
+ - Isolation routes use Expo Router: `app/isolated-components/ComponentName.tsx` (not a `/page.tsx` subdirectory)
190
+ - Capture wrappers use `nativeID="codeyam-capture"` (not `id="codeyam-capture"`) — `nativeID` maps to `id` on web
191
+ - The preview renders via react-native-web in a browser — some visual differences from native devices are expected (fonts, SafeAreaView, shadows). See `MOBILE_SETUP.md` for details.
192
+
178
193
  ## Quick Reference
179
194
 
180
195
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeyam/codeyam-cli",
3
- "version": "0.1.0-staging.b147f46",
3
+ "version": "0.1.0-staging.b49802d",
4
4
  "description": "Local development CLI for CodeYam analysis",
5
5
  "type": "module",
6
6
  "bin": {
@@ -91,7 +91,13 @@ export default async function loadAnalysis({ id, analysisBranchId, projectId, fi
91
91
  const analysis = await query.executeTakeFirst();
92
92
  const queryTime = Date.now() - startTime;
93
93
  if (!analysis) {
94
- awsLog(`CodeYam Error: Analysis not found${entityName ? ` for ${entityName}` : ''}${id ? ` (id=${id})` : ''}`, null, {
94
+ // When queried by dependencyAnalyzedTreeSha, this is a cache check
95
+ // (findValidExistingAnalysis pattern). Not finding a cached analysis is
96
+ // expected for new entities — log as debug, not error.
97
+ const isExpectedMiss = !!dependencyAnalyzedTreeSha;
98
+ awsLog(isExpectedMiss
99
+ ? `CodeYam: Analysis cache miss for dependency tree SHA ${dependencyAnalyzedTreeSha.substring(0, 12)}...`
100
+ : `CodeYam Error: Analysis not found${entityName ? ` for ${entityName}` : ''}${id ? ` (id=${id})` : ''}`, null, {
95
101
  id,
96
102
  analysisBranchId,
97
103
  projectId,
@@ -1 +1 @@
1
- {"version":3,"file":"loadAnalysis.js","sourceRoot":"","sources":["../../../../../../packages/database/src/lib/loadAnalysis.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loadAnalysis.js","sourceRoot":"","sources":["../../../../../../packages/database/src/lib/loadAnalysis.ts"],"names":[],"mappings":"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"}
@@ -1,34 +0,0 @@
1
- import{d as P,r as t}from"./chunk-JZWAC4HX-BAdwhyCx.js";import{u as _}from"./useLastLogLine-BNd5hYuW.js";import{j as y}from"./jsx-runtime-D_zvdyIk.js";function R(s){const o=s.replace(/[^a-zA-Z0-9_]+/g,"_");return o.slice(0,1).toUpperCase()+o.slice(1)}function G({analysisId:s,scenarioId:o,scenarioName:i,entityName:c,projectSlug:m,enabled:x=!0,refreshTrigger:p=0}){const k=P(),[b,E]=t.useState(null),[q,U]=t.useState(!1),[z,u]=t.useState(!1),[A,f]=t.useState(!1),v=t.useRef(!1),I=t.useRef(null),g=t.useRef(null),h=t.useRef(null),[F,w]=t.useState(0),[j,M]=t.useState(0),r=t.useRef(null),l=t.useRef(!1),{interactiveUrl:L,resetLogs:T}=_(m,x),C=t.useRef(o),B=t.useRef(p);t.useEffect(()=>{B.current!==p&&(B.current=p,b&&(console.log("[useInteractiveMode] Manual refresh triggered"),u(!0),f(!1),w(0),M(e=>e+1),l.current=!1,r.current&&(clearTimeout(r.current),r.current=null)))},[p,b]),t.useEffect(()=>{if(C.current!==o&&(C.current=o,I.current&&g.current&&i)){let e=I.current;if(h.current&&c){const a=R(h.current),d=R(c);a!==d&&(e=e.replace(a,d),h.current=c)}const n=R(g.current),S=R(i);e=e.replace(n,S),g.current=i,E(e),u(!0),f(!1),w(0),M(a=>a+1),l.current=!1,r.current&&(clearTimeout(r.current),r.current=null);return}},[o,i,c]),t.useEffect(()=>{if(L){const e=L+"?width=600px";I.current=e,i&&(g.current=i),c&&(h.current=c),E(e),U(!1),u(!0)}},[L]),t.useEffect(()=>{const e=n=>{n.data.type==="codeyam-resize"&&(l.current||(l.current=!0,r.current&&(clearTimeout(r.current),r.current=null),w(0),f(!0),requestAnimationFrame(()=>{requestAnimationFrame(()=>{u(!1)})})))};return window.addEventListener("message",e),()=>window.removeEventListener("message",e)},[]);const D=()=>{l.current=!1,r.current&&clearTimeout(r.current);const e=300*Math.pow(2,F);r.current=setTimeout(()=>{l.current||(F<2?(w(n=>n+1),M(n=>n+1),u(!0)):(console.error("[useInteractiveMode] Interactive mode failed to load after 3 attempts - showing iframe anyway"),f(!0),u(!1)))},e)};return t.useEffect(()=>{x&&!v.current&&o&&s&&(v.current=!0,U(!0),f(!1),E(null),(async()=>{if(m)try{await fetch(`/api/logs/${m}`,{method:"DELETE"})}catch(n){console.error("[useInteractiveMode] Failed to clear log file:",n)}T(),k.submit({action:"start",analysisId:s,scenarioId:o},{method:"post",action:"/api/interactive-mode"})})())},[x,o,s,T,m]),t.useEffect(()=>{const e=s,n=()=>{if(v.current&&e){const a=new URLSearchParams({action:"stop",analysisId:e});console.log("[useInteractiveMode] Sending stop request via sendBeacon");const d=navigator.sendBeacon("/api/interactive-mode",a);console.log("[useInteractiveMode] sendBeacon result:",d),d||(console.log("[useInteractiveMode] sendBeacon failed, using fetch fallback"),fetch("/api/interactive-mode",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:a,keepalive:!0}).catch(K=>console.error("Failed to stop interactive mode:",K)))}},S=()=>{n()};return window.addEventListener("beforeunload",S),()=>{window.removeEventListener("beforeunload",S),console.log("[useInteractiveMode] Cleanup running:",{hasStarted:v.current,analysisId:e}),n()}},[s]),{interactiveServerUrl:b,isStarting:q,isLoading:z,showIframe:A,iframeKey:j,onIframeLoad:D}}function H(){return y.jsxs("div",{className:"spinner-container",children:[y.jsx("span",{className:"loader"}),y.jsx("style",{children:`
2
- .loader {
3
- width: 48px;
4
- height: 48px;
5
- border: 3px solid rgba(0, 92, 117, 0.2);
6
- border-radius: 50%;
7
- display: inline-block;
8
- position: relative;
9
- box-sizing: border-box;
10
- animation: rotation 1s linear infinite;
11
- }
12
- .loader::after {
13
- content: '';
14
- box-sizing: border-box;
15
- position: absolute;
16
- left: 50%;
17
- top: 50%;
18
- transform: translate(-50%, -50%);
19
- width: 56px;
20
- height: 56px;
21
- border-radius: 50%;
22
- border: 3px solid;
23
- border-color: #005c75 transparent;
24
- }
25
-
26
- @keyframes rotation {
27
- 0% {
28
- transform: rotate(0deg);
29
- }
30
- 100% {
31
- transform: rotate(360deg);
32
- }
33
- }
34
- `})]})}export{H as S,G as u};