@codeyam/codeyam-cli 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) 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 +4 -4
  4. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +0 -33
  5. package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +13 -7
  6. package/analyzer-template/packages/analyze/src/lib/asts/index.ts +7 -2
  7. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +0 -98
  8. package/analyzer-template/packages/aws/package.json +1 -1
  9. package/analyzer-template/packages/database/src/lib/kysely/tables/editorScenariosTable.ts +31 -0
  10. package/analyzer-template/packages/database/src/lib/loadEntities.ts +0 -6
  11. package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +0 -65
  12. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts +5 -0
  13. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts.map +1 -1
  14. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js +31 -0
  15. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -1
  16. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts.map +1 -1
  17. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js +0 -6
  18. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js.map +1 -1
  19. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
  20. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +0 -25
  21. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js.map +1 -1
  22. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.d.ts +2 -0
  23. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.d.ts.map +1 -1
  24. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.js +2 -0
  25. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.js.map +1 -1
  26. package/analyzer-template/packages/types/src/enums/ProjectFramework.ts +2 -0
  27. package/analyzer-template/packages/ui-components/package.json +1 -1
  28. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.d.ts +2 -0
  29. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.d.ts.map +1 -1
  30. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.js +2 -0
  31. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.js.map +1 -1
  32. package/codeyam-cli/src/__tests__/memory-scripts/filter-session.test.js +196 -0
  33. package/codeyam-cli/src/__tests__/memory-scripts/filter-session.test.js.map +1 -0
  34. package/codeyam-cli/src/__tests__/memory-scripts/read-json-field.test.js +114 -0
  35. package/codeyam-cli/src/__tests__/memory-scripts/read-json-field.test.js.map +1 -0
  36. package/codeyam-cli/src/__tests__/memory-scripts/ripgrep-fallback.test.js +149 -0
  37. package/codeyam-cli/src/__tests__/memory-scripts/ripgrep-fallback.test.js.map +1 -0
  38. package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js +45 -0
  39. package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js.map +1 -0
  40. package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js +101 -47
  41. package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js.map +1 -1
  42. package/codeyam-cli/src/commands/default.js +3 -46
  43. package/codeyam-cli/src/commands/default.js.map +1 -1
  44. package/codeyam-cli/src/commands/editor.js +1619 -243
  45. package/codeyam-cli/src/commands/editor.js.map +1 -1
  46. package/codeyam-cli/src/commands/init.js +67 -34
  47. package/codeyam-cli/src/commands/init.js.map +1 -1
  48. package/codeyam-cli/src/data/techStacks.js +77 -0
  49. package/codeyam-cli/src/data/techStacks.js.map +1 -0
  50. package/codeyam-cli/src/utils/__tests__/analyzerFinalization.test.js +144 -0
  51. package/codeyam-cli/src/utils/__tests__/analyzerFinalization.test.js.map +1 -0
  52. package/codeyam-cli/src/utils/__tests__/backgroundServer.test.js +46 -0
  53. package/codeyam-cli/src/utils/__tests__/backgroundServer.test.js.map +1 -0
  54. package/codeyam-cli/src/utils/__tests__/devServerState.test.js +134 -0
  55. package/codeyam-cli/src/utils/__tests__/devServerState.test.js.map +1 -0
  56. package/codeyam-cli/src/utils/__tests__/editorApi.test.js +127 -0
  57. package/codeyam-cli/src/utils/__tests__/editorApi.test.js.map +1 -0
  58. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +610 -1
  59. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
  60. package/codeyam-cli/src/utils/__tests__/editorCapture.test.js +93 -0
  61. package/codeyam-cli/src/utils/__tests__/editorCapture.test.js.map +1 -0
  62. package/codeyam-cli/src/utils/__tests__/editorDevServer.test.js +181 -3
  63. package/codeyam-cli/src/utils/__tests__/editorDevServer.test.js.map +1 -1
  64. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js +121 -0
  65. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js.map +1 -0
  66. package/codeyam-cli/src/utils/__tests__/editorImageVerifier.test.js +294 -0
  67. package/codeyam-cli/src/utils/__tests__/editorImageVerifier.test.js.map +1 -0
  68. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js +249 -2
  69. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js.map +1 -1
  70. package/codeyam-cli/src/utils/__tests__/editorLoaderHelpers.test.js +520 -0
  71. package/codeyam-cli/src/utils/__tests__/editorLoaderHelpers.test.js.map +1 -0
  72. package/codeyam-cli/src/utils/__tests__/editorPreloadHelpers.test.js +118 -1
  73. package/codeyam-cli/src/utils/__tests__/editorPreloadHelpers.test.js.map +1 -1
  74. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js +195 -3
  75. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js.map +1 -1
  76. package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js +153 -0
  77. package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js.map +1 -0
  78. package/codeyam-cli/src/utils/__tests__/editorScenarioLookup.test.js +139 -0
  79. package/codeyam-cli/src/utils/__tests__/editorScenarioLookup.test.js.map +1 -0
  80. package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js +221 -0
  81. package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js.map +1 -0
  82. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js +781 -2
  83. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -1
  84. package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js +213 -0
  85. package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js.map +1 -0
  86. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js +1742 -0
  87. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js.map +1 -0
  88. package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js +107 -0
  89. package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js.map +1 -0
  90. package/codeyam-cli/src/utils/__tests__/parseRegisterArg.test.js +101 -0
  91. package/codeyam-cli/src/utils/__tests__/parseRegisterArg.test.js.map +1 -0
  92. package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js +227 -0
  93. package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js.map +1 -0
  94. package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js +300 -0
  95. package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js.map +1 -0
  96. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +25 -5
  97. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  98. package/codeyam-cli/src/utils/__tests__/templateConsistency.test.js +51 -0
  99. package/codeyam-cli/src/utils/__tests__/templateConsistency.test.js.map +1 -0
  100. package/codeyam-cli/src/utils/__tests__/webappDetection.test.js +142 -0
  101. package/codeyam-cli/src/utils/__tests__/webappDetection.test.js.map +1 -0
  102. package/codeyam-cli/src/utils/analyzer.js +9 -0
  103. package/codeyam-cli/src/utils/analyzer.js.map +1 -1
  104. package/codeyam-cli/src/utils/analyzerFinalization.js +96 -0
  105. package/codeyam-cli/src/utils/analyzerFinalization.js.map +1 -0
  106. package/codeyam-cli/src/utils/backgroundServer.js +94 -18
  107. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  108. package/codeyam-cli/src/utils/database.js +37 -2
  109. package/codeyam-cli/src/utils/database.js.map +1 -1
  110. package/codeyam-cli/src/utils/devServerState.js +71 -0
  111. package/codeyam-cli/src/utils/devServerState.js.map +1 -0
  112. package/codeyam-cli/src/utils/editorApi.js +73 -0
  113. package/codeyam-cli/src/utils/editorApi.js.map +1 -0
  114. package/codeyam-cli/src/utils/editorAudit.js +101 -7
  115. package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
  116. package/codeyam-cli/src/utils/editorCapture.js +102 -0
  117. package/codeyam-cli/src/utils/editorCapture.js.map +1 -0
  118. package/codeyam-cli/src/utils/editorDevServer.js +100 -1
  119. package/codeyam-cli/src/utils/editorDevServer.js.map +1 -1
  120. package/codeyam-cli/src/utils/editorEntityChangeStatus.js +44 -0
  121. package/codeyam-cli/src/utils/editorEntityChangeStatus.js.map +1 -0
  122. package/codeyam-cli/src/utils/editorImageVerifier.js +155 -0
  123. package/codeyam-cli/src/utils/editorImageVerifier.js.map +1 -0
  124. package/codeyam-cli/src/utils/editorJournal.js +92 -4
  125. package/codeyam-cli/src/utils/editorJournal.js.map +1 -1
  126. package/codeyam-cli/src/utils/editorLoaderHelpers.js +113 -0
  127. package/codeyam-cli/src/utils/editorLoaderHelpers.js.map +1 -0
  128. package/codeyam-cli/src/utils/editorMockState.js +1 -1
  129. package/codeyam-cli/src/utils/editorPreloadHelpers.js +72 -1
  130. package/codeyam-cli/src/utils/editorPreloadHelpers.js.map +1 -1
  131. package/codeyam-cli/src/utils/editorPreview.js +67 -1
  132. package/codeyam-cli/src/utils/editorPreview.js.map +1 -1
  133. package/codeyam-cli/src/utils/editorScenarioSwitch.js +112 -0
  134. package/codeyam-cli/src/utils/editorScenarioSwitch.js.map +1 -0
  135. package/codeyam-cli/src/utils/editorScenarios.js +276 -0
  136. package/codeyam-cli/src/utils/editorScenarios.js.map +1 -1
  137. package/codeyam-cli/src/utils/editorSeedAdapter.js +173 -0
  138. package/codeyam-cli/src/utils/editorSeedAdapter.js.map +1 -0
  139. package/codeyam-cli/src/utils/entityChangeStatus.js +349 -0
  140. package/codeyam-cli/src/utils/entityChangeStatus.js.map +1 -0
  141. package/codeyam-cli/src/utils/entityChangeStatus.server.js +158 -0
  142. package/codeyam-cli/src/utils/entityChangeStatus.server.js.map +1 -0
  143. package/codeyam-cli/src/utils/install-skills.js +1 -1
  144. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  145. package/codeyam-cli/src/utils/parseRegisterArg.js +31 -0
  146. package/codeyam-cli/src/utils/parseRegisterArg.js.map +1 -0
  147. package/codeyam-cli/src/utils/scenarioCoverage.js +75 -0
  148. package/codeyam-cli/src/utils/scenarioCoverage.js.map +1 -0
  149. package/codeyam-cli/src/utils/scenariosManifest.js +159 -0
  150. package/codeyam-cli/src/utils/scenariosManifest.js.map +1 -0
  151. package/codeyam-cli/src/utils/serverState.js +30 -0
  152. package/codeyam-cli/src/utils/serverState.js.map +1 -1
  153. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +46 -16
  154. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  155. package/codeyam-cli/src/utils/simulationGateMiddleware.js +8 -1
  156. package/codeyam-cli/src/utils/simulationGateMiddleware.js.map +1 -1
  157. package/codeyam-cli/src/utils/slugUtils.js +25 -0
  158. package/codeyam-cli/src/utils/slugUtils.js.map +1 -0
  159. package/codeyam-cli/src/utils/syncMocksMiddleware.js +2 -2
  160. package/codeyam-cli/src/utils/syncMocksMiddleware.js.map +1 -1
  161. package/codeyam-cli/src/utils/webappDetection.js +21 -0
  162. package/codeyam-cli/src/utils/webappDetection.js.map +1 -1
  163. package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js +40 -0
  164. package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js.map +1 -0
  165. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js +567 -0
  166. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js.map +1 -0
  167. package/codeyam-cli/src/webserver/app/lib/clientErrors.js +65 -0
  168. package/codeyam-cli/src/webserver/app/lib/clientErrors.js.map +1 -0
  169. package/codeyam-cli/src/webserver/app/lib/git.js +397 -0
  170. package/codeyam-cli/src/webserver/app/lib/git.js.map +1 -0
  171. package/codeyam-cli/src/webserver/build/client/assets/{CopyButton-DmJveP3T.js → CopyButton-BPXZwM4t.js} +1 -1
  172. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-C76mRRiF.js → EntityItem-BcgbViKV.js} +3 -3
  173. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-CobE682z.js → EntityTypeIcon-CQIG2qda.js} +9 -9
  174. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-djPLI-WV.js → ReportIssueModal-BzHcG7SE.js} +3 -3
  175. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-B76aig_2.js → ScenarioViewer-Bd-hxofb.js} +3 -3
  176. package/codeyam-cli/src/webserver/build/client/assets/ViewportInspectBar-oAf2Kqsf.js +1 -0
  177. package/codeyam-cli/src/webserver/build/client/assets/{_index-C96V0n15.js → _index-DLxKhri3.js} +3 -3
  178. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BpKzcsJz.js → activity.(_tab)-BcY3q6nt.js} +6 -6
  179. package/codeyam-cli/src/webserver/build/client/assets/addon-canvas-DpzMmAy5.js +1 -0
  180. package/codeyam-cli/src/webserver/build/client/assets/addon-fit-YJmn1quW.js +12 -0
  181. package/codeyam-cli/src/webserver/build/client/assets/addon-webgl-DI8QOUvO.js +58 -0
  182. package/codeyam-cli/src/webserver/build/client/assets/{agent-transcripts-D9hemwl6.js → agent-transcripts-Bni3iiUj.js} +5 -5
  183. package/codeyam-cli/src/webserver/build/client/assets/api.editor-file-diff-l0sNRNKZ.js +1 -0
  184. package/codeyam-cli/src/webserver/build/client/assets/api.editor-file-l0sNRNKZ.js +1 -0
  185. package/codeyam-cli/src/webserver/build/client/assets/api.editor-project-info-l0sNRNKZ.js +1 -0
  186. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-coverage-l0sNRNKZ.js +1 -0
  187. package/codeyam-cli/src/webserver/build/client/assets/{book-open-D_nMCFmP.js → book-open-BYOypzCa.js} +2 -2
  188. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-BH2h1Ea2.js → chevron-down-C_Pmso5S.js} +2 -2
  189. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-DyIKORY6.js → circle-check-BVMi9VA5.js} +2 -2
  190. package/codeyam-cli/src/webserver/build/client/assets/{copy-NDbZjXao.js → copy-n2FB0_Sw.js} +3 -3
  191. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CC6AbExI.js +41 -0
  192. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BsDh6TSF.js +1 -0
  193. package/codeyam-cli/src/webserver/build/client/assets/editor-PBc_6L9R.js +10 -0
  194. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-4FzHlcNn.js +41 -0
  195. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-CrjR3zZW.js → entity._sha._-BsDXNp45.js} +3 -3
  196. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-BgAqUtTZ.js +6 -0
  197. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-Bmshgrij.js +6 -0
  198. package/codeyam-cli/src/webserver/build/client/assets/{files-DO4CZ16O.js → files-BZrlFE1F.js} +1 -1
  199. package/codeyam-cli/src/webserver/build/client/assets/git-DdZcvjGh.js +1 -0
  200. package/codeyam-cli/src/webserver/build/client/assets/globals-B8vTTNy2.css +1 -0
  201. package/codeyam-cli/src/webserver/build/client/assets/index-yHOVb4rc.js +15 -0
  202. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-BAXYRVEO.js → loader-circle-DaAZ_H2w.js} +2 -2
  203. package/codeyam-cli/src/webserver/build/client/assets/manifest-65850841.js +1 -0
  204. package/codeyam-cli/src/webserver/build/client/assets/memory-9gnxSZlb.js +101 -0
  205. package/codeyam-cli/src/webserver/build/client/assets/{pause-DTAcYxBt.js → pause-f5-1lKBt.js} +3 -3
  206. package/codeyam-cli/src/webserver/build/client/assets/root-BwX8YgFb.js +67 -0
  207. package/codeyam-cli/src/webserver/build/client/assets/{search-fKo7v0Zo.js → search-Di64LWVb.js} +2 -2
  208. package/codeyam-cli/src/webserver/build/client/assets/{settings-DfuTtcJP.js → settings-0OrEMU6J.js} +1 -1
  209. package/codeyam-cli/src/webserver/build/client/assets/{simulations-B3aOzpCZ.js → simulations-DWT-CvLy.js} +1 -1
  210. package/codeyam-cli/src/webserver/build/client/assets/{terminal-BG4heKCG.js → terminal-Br7MOqts.js} +3 -3
  211. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-DtSmdtM4.js → triangle-alert-BLdiCuG-.js} +2 -2
  212. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-BE43Hjti.js +1 -0
  213. package/codeyam-cli/src/webserver/build/server/assets/index-DEEQf4pi.js +1 -0
  214. package/codeyam-cli/src/webserver/build/server/assets/init-CkWmyFY2.js +10 -0
  215. package/codeyam-cli/src/webserver/build/server/assets/server-build-BHi-9O8W.js +439 -0
  216. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  217. package/codeyam-cli/src/webserver/build-info.json +5 -5
  218. package/codeyam-cli/src/webserver/editorProxy.js +487 -50
  219. package/codeyam-cli/src/webserver/editorProxy.js.map +1 -1
  220. package/codeyam-cli/src/webserver/scripts/codeyam-preload.mjs +242 -3
  221. package/codeyam-cli/src/webserver/scripts/journalCapture.ts +94 -4
  222. package/codeyam-cli/src/webserver/server.js +46 -14
  223. package/codeyam-cli/src/webserver/server.js.map +1 -1
  224. package/codeyam-cli/src/webserver/terminalServer.js +39 -11
  225. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
  226. package/codeyam-cli/templates/chrome-extension-react/EXTENSION_SETUP.md +75 -0
  227. package/codeyam-cli/templates/chrome-extension-react/README.md +46 -0
  228. package/codeyam-cli/templates/chrome-extension-react/gitignore +15 -0
  229. package/codeyam-cli/templates/chrome-extension-react/index.html +12 -0
  230. package/codeyam-cli/templates/chrome-extension-react/package.json +27 -0
  231. package/codeyam-cli/templates/chrome-extension-react/popup.html +12 -0
  232. package/codeyam-cli/templates/chrome-extension-react/public/manifest.json +15 -0
  233. package/codeyam-cli/templates/chrome-extension-react/src/background/service-worker.ts +7 -0
  234. package/codeyam-cli/templates/chrome-extension-react/src/globals.css +6 -0
  235. package/codeyam-cli/templates/chrome-extension-react/src/lib/storage.ts +37 -0
  236. package/codeyam-cli/templates/chrome-extension-react/src/popup/App.tsx +12 -0
  237. package/codeyam-cli/templates/chrome-extension-react/src/popup/main.tsx +10 -0
  238. package/codeyam-cli/templates/chrome-extension-react/tsconfig.json +24 -0
  239. package/codeyam-cli/templates/chrome-extension-react/vite.config.ts +41 -0
  240. package/codeyam-cli/templates/codeyam-editor-claude.md +84 -5
  241. package/codeyam-cli/templates/editor-step-hook.py +97 -8
  242. package/codeyam-cli/templates/expo-react-native/MOBILE_SETUP.md +89 -0
  243. package/codeyam-cli/templates/expo-react-native/README.md +41 -0
  244. package/codeyam-cli/templates/expo-react-native/app/(tabs)/_layout.tsx +33 -0
  245. package/codeyam-cli/templates/expo-react-native/app/(tabs)/index.tsx +12 -0
  246. package/codeyam-cli/templates/expo-react-native/app/(tabs)/settings.tsx +12 -0
  247. package/codeyam-cli/templates/expo-react-native/app/_layout.tsx +12 -0
  248. package/codeyam-cli/templates/expo-react-native/app.json +18 -0
  249. package/codeyam-cli/templates/expo-react-native/babel.config.js +9 -0
  250. package/codeyam-cli/templates/expo-react-native/gitignore +12 -0
  251. package/codeyam-cli/templates/expo-react-native/global.css +3 -0
  252. package/codeyam-cli/templates/expo-react-native/lib/storage.ts +32 -0
  253. package/codeyam-cli/templates/expo-react-native/metro.config.js +6 -0
  254. package/codeyam-cli/templates/expo-react-native/nativewind-env.d.ts +1 -0
  255. package/codeyam-cli/templates/expo-react-native/package.json +38 -0
  256. package/codeyam-cli/templates/expo-react-native/tailwind.config.js +10 -0
  257. package/codeyam-cli/templates/expo-react-native/tsconfig.json +10 -0
  258. package/codeyam-cli/templates/nextjs-prisma-sqlite/AUTH_PATTERNS.md +308 -0
  259. package/codeyam-cli/templates/nextjs-prisma-sqlite/AUTH_UPGRADE.md +304 -0
  260. package/codeyam-cli/templates/nextjs-prisma-sqlite/DATABASE.md +126 -0
  261. package/codeyam-cli/templates/nextjs-prisma-sqlite/FEATURE_PATTERNS.md +37 -0
  262. package/codeyam-cli/templates/nextjs-prisma-sqlite/README.md +53 -0
  263. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/codeyam-isolate/layout.tsx +12 -0
  264. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/lib/prisma.ts +9 -4
  265. package/codeyam-cli/templates/nextjs-prisma-sqlite/env +4 -0
  266. package/codeyam-cli/templates/nextjs-prisma-sqlite/gitignore +21 -0
  267. package/codeyam-cli/templates/nextjs-prisma-sqlite/package.json +5 -1
  268. package/codeyam-cli/templates/nextjs-prisma-sqlite/prisma/seed.ts +4 -1
  269. package/codeyam-cli/templates/nextjs-prisma-sqlite/seed-adapter.ts +92 -0
  270. package/codeyam-cli/templates/nextjs-prisma-sqlite/vitest.config.ts +13 -0
  271. package/codeyam-cli/templates/nextjs-prisma-supabase/README.md +52 -0
  272. package/codeyam-cli/templates/{nextjs-prisma-sqlite/PRISMA_SETUP.md → nextjs-prisma-supabase/SUPABASE_SETUP.md} +37 -17
  273. package/codeyam-cli/templates/nextjs-prisma-supabase/app/api/todos/route.ts +17 -0
  274. package/codeyam-cli/templates/nextjs-prisma-supabase/app/globals.css +26 -0
  275. package/codeyam-cli/templates/nextjs-prisma-supabase/app/layout.tsx +34 -0
  276. package/codeyam-cli/templates/nextjs-prisma-supabase/app/lib/prisma.ts +20 -0
  277. package/codeyam-cli/templates/nextjs-prisma-supabase/app/lib/supabase.ts +12 -0
  278. package/codeyam-cli/templates/nextjs-prisma-supabase/app/page.tsx +10 -0
  279. package/codeyam-cli/templates/nextjs-prisma-supabase/env +9 -0
  280. package/codeyam-cli/templates/nextjs-prisma-supabase/eslint.config.mjs +11 -0
  281. package/codeyam-cli/templates/nextjs-prisma-supabase/gitignore +40 -0
  282. package/codeyam-cli/templates/nextjs-prisma-supabase/next.config.ts +11 -0
  283. package/codeyam-cli/templates/nextjs-prisma-supabase/package.json +37 -0
  284. package/codeyam-cli/templates/nextjs-prisma-supabase/postcss.config.mjs +7 -0
  285. package/codeyam-cli/templates/nextjs-prisma-supabase/prisma/schema.prisma +27 -0
  286. package/codeyam-cli/templates/nextjs-prisma-supabase/prisma/seed.ts +39 -0
  287. package/codeyam-cli/templates/nextjs-prisma-supabase/prisma.config.ts +12 -0
  288. package/codeyam-cli/templates/nextjs-prisma-supabase/tsconfig.json +34 -0
  289. package/codeyam-cli/templates/skills/codeyam-dev-mode/SKILL.md +2 -2
  290. package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +96 -17
  291. package/codeyam-cli/templates/skills/codeyam-memory/SKILL.md +10 -10
  292. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/detect-deprecated-patterns.mjs +139 -0
  293. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/find-exports.mjs +52 -0
  294. package/codeyam-cli/templates/skills/codeyam-memory/scripts/lib/read-json-field.mjs +61 -0
  295. package/codeyam-cli/templates/skills/codeyam-memory/scripts/lib/ripgrep-fallback.mjs +155 -0
  296. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/cleanup.mjs +13 -0
  297. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/filter-session.mjs +95 -0
  298. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/preprocess.mjs +160 -0
  299. package/package.json +14 -9
  300. package/packages/ai/src/lib/generateExecutionFlows.js +0 -11
  301. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
  302. package/packages/analyze/src/lib/ProjectAnalyzer.js +10 -4
  303. package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
  304. package/packages/analyze/src/lib/asts/index.js +4 -2
  305. package/packages/analyze/src/lib/asts/index.js.map +1 -1
  306. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +0 -40
  307. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -1
  308. package/packages/database/src/lib/kysely/tables/editorScenariosTable.js +31 -0
  309. package/packages/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -1
  310. package/packages/database/src/lib/loadEntities.js +0 -6
  311. package/packages/database/src/lib/loadEntities.js.map +1 -1
  312. package/packages/database/src/lib/updateCommitMetadata.js +0 -25
  313. package/packages/database/src/lib/updateCommitMetadata.js.map +1 -1
  314. package/packages/types/src/enums/ProjectFramework.js +2 -0
  315. package/packages/types/src/enums/ProjectFramework.js.map +1 -1
  316. package/codeyam-cli/src/webserver/build/client/assets/Terminal-Dnj5CY9R.js +0 -41
  317. package/codeyam-cli/src/webserver/build/client/assets/addon-fit-CUXOrorO.js +0 -1
  318. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CMT1jU2q.js +0 -21
  319. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BiM6z3Do.js +0 -1
  320. package/codeyam-cli/src/webserver/build/client/assets/editor-D1DAKXtT.js +0 -8
  321. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-DkzqFzFj.js +0 -6
  322. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-C28BiQzt.js +0 -6
  323. package/codeyam-cli/src/webserver/build/client/assets/git-CFCTYk9I.js +0 -15
  324. package/codeyam-cli/src/webserver/build/client/assets/globals-B17TBSS6.css +0 -1
  325. package/codeyam-cli/src/webserver/build/client/assets/manifest-a632de18.js +0 -1
  326. package/codeyam-cli/src/webserver/build/client/assets/memory-Dg0mvYrI.js +0 -96
  327. package/codeyam-cli/src/webserver/build/client/assets/root-DUKqhFlb.js +0 -67
  328. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-ByhSyh0W.js +0 -1
  329. package/codeyam-cli/src/webserver/build/server/assets/index-HfLydfDq.js +0 -1
  330. package/codeyam-cli/src/webserver/build/server/assets/server-build-CUu_F-oo.js +0 -366
  331. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/detect-deprecated-patterns.sh +0 -108
  332. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/find-exports.sh +0 -69
  333. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/cleanup.sh +0 -12
  334. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/filter.jq +0 -45
  335. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/preprocess.sh +0 -139
@@ -0,0 +1,308 @@
1
+ # Auth Patterns for Dev Prototyping
2
+
3
+ This project uses a simple cookie + database auth pattern designed for local development.
4
+ It is **intentionally simple** — built for easy upgrade to a real provider later.
5
+
6
+ ## DO NOT use external auth providers during prototyping
7
+
8
+ **Do NOT use NextAuth, Auth.js, Clerk, better-auth, Supabase Auth, or any external auth provider.**
9
+
10
+ These providers require external infrastructure (OAuth endpoints, JWT signing keys, callback URLs)
11
+ that is unavailable in the local SQLite development environment. They will fail silently or produce
12
+ confusing errors. Use the pattern below instead — it works immediately and upgrades cleanly later.
13
+
14
+ See `AUTH_UPGRADE.md` for how to swap in a real provider when going to production.
15
+
16
+ ## Interfaces
17
+
18
+ All consumer code imports from `@/app/lib/auth`. The interface is:
19
+
20
+ ```typescript
21
+ export interface AuthUser {
22
+ id: string;
23
+ name: string;
24
+ email: string;
25
+ image?: string | null;
26
+ }
27
+
28
+ export interface Session {
29
+ user: AuthUser;
30
+ }
31
+
32
+ export async function getSession(): Promise<Session | null>;
33
+ export async function requireAuth(): Promise<Session>; // redirects to /login if no session
34
+ export async function signIn(
35
+ email: string,
36
+ password: string,
37
+ ): Promise<Session | null>;
38
+ export async function signOut(): Promise<void>;
39
+ ```
40
+
41
+ ## Prisma Schema Additions
42
+
43
+ Add these models to `prisma/schema.prisma`:
44
+
45
+ ```prisma
46
+ model User {
47
+ id String @id @default(cuid())
48
+ name String
49
+ email String @unique
50
+ password String
51
+ image String?
52
+ sessions Session[]
53
+ createdAt DateTime @default(now())
54
+ }
55
+
56
+ model Session {
57
+ id String @id @default(cuid())
58
+ token String @unique
59
+ userId String
60
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
61
+ createdAt DateTime @default(now())
62
+ }
63
+ ```
64
+
65
+ After editing the schema, run: `npm run db:push`
66
+
67
+ ## Dev Implementation: `app/lib/auth.ts`
68
+
69
+ ```typescript
70
+ import { cookies } from 'next/headers';
71
+ import { redirect } from 'next/navigation';
72
+ import { prisma } from '@/app/lib/prisma';
73
+
74
+ export interface AuthUser {
75
+ id: string;
76
+ name: string;
77
+ email: string;
78
+ image?: string | null;
79
+ }
80
+
81
+ export interface Session {
82
+ user: AuthUser;
83
+ }
84
+
85
+ const COOKIE_NAME = 'session-token';
86
+
87
+ export async function getSession(): Promise<Session | null> {
88
+ const cookieStore = await cookies();
89
+ const token = cookieStore.get(COOKIE_NAME)?.value;
90
+ if (!token) return null;
91
+
92
+ const session = await prisma.session.findUnique({
93
+ where: { token },
94
+ include: { user: true },
95
+ });
96
+ if (!session) return null;
97
+
98
+ return {
99
+ user: {
100
+ id: session.user.id,
101
+ name: session.user.name,
102
+ email: session.user.email,
103
+ image: session.user.image,
104
+ },
105
+ };
106
+ }
107
+
108
+ export async function requireAuth(): Promise<Session> {
109
+ const session = await getSession();
110
+ if (!session) redirect('/login');
111
+ return session;
112
+ }
113
+
114
+ export async function signIn(
115
+ email: string,
116
+ password: string,
117
+ ): Promise<Session | null> {
118
+ const user = await prisma.user.findUnique({ where: { email } });
119
+ if (!user || user.password !== password) return null;
120
+
121
+ const token = crypto.randomUUID();
122
+ await prisma.session.create({
123
+ data: { token, userId: user.id },
124
+ });
125
+
126
+ const cookieStore = await cookies();
127
+ cookieStore.set(COOKIE_NAME, token, {
128
+ httpOnly: true,
129
+ path: '/',
130
+ sameSite: 'lax',
131
+ });
132
+
133
+ return {
134
+ user: {
135
+ id: user.id,
136
+ name: user.name,
137
+ email: user.email,
138
+ image: user.image,
139
+ },
140
+ };
141
+ }
142
+
143
+ export async function signOut(): Promise<void> {
144
+ const cookieStore = await cookies();
145
+ const token = cookieStore.get(COOKIE_NAME)?.value;
146
+ if (token) {
147
+ await prisma.session.deleteMany({ where: { token } });
148
+ }
149
+ cookieStore.delete(COOKIE_NAME);
150
+ }
151
+ ```
152
+
153
+ ## Cookie Name
154
+
155
+ The cookie name **must be `session-token`**. The CodeYam proxy uses this name for
156
+ scenario auto-login (injecting/clearing the cookie when switching between scenarios).
157
+
158
+ ## API Routes
159
+
160
+ ### `/api/auth/login` (POST)
161
+
162
+ ```typescript
163
+ import { signIn } from '@/app/lib/auth';
164
+ import { NextResponse } from 'next/server';
165
+
166
+ export async function POST(request: Request) {
167
+ const { email, password } = await request.json();
168
+ const session = await signIn(email, password);
169
+ if (!session) {
170
+ return NextResponse.json({ error: 'Invalid credentials' }, { status: 401 });
171
+ }
172
+ return NextResponse.json({ user: session.user });
173
+ }
174
+ ```
175
+
176
+ ### `/api/auth/logout` (POST)
177
+
178
+ ```typescript
179
+ import { signOut } from '@/app/lib/auth';
180
+ import { NextResponse } from 'next/server';
181
+
182
+ export async function POST() {
183
+ await signOut();
184
+ return NextResponse.json({ success: true });
185
+ }
186
+ ```
187
+
188
+ ### `/api/auth/session` (GET) — for client components
189
+
190
+ ```typescript
191
+ import { getSession } from '@/app/lib/auth';
192
+ import { NextResponse } from 'next/server';
193
+
194
+ export async function GET() {
195
+ const session = await getSession();
196
+ return NextResponse.json({ session });
197
+ }
198
+ ```
199
+
200
+ ## Usage in Server Components
201
+
202
+ ```typescript
203
+ import { getSession } from '@/app/lib/auth';
204
+
205
+ export default async function Dashboard() {
206
+ const session = await getSession();
207
+ if (!session) redirect('/login');
208
+
209
+ return <h1>Welcome, {session.user.name}</h1>;
210
+ }
211
+ ```
212
+
213
+ ## Usage in Client Components
214
+
215
+ ```typescript
216
+ 'use client';
217
+ import { useEffect, useState } from 'react';
218
+
219
+ export function UserNav() {
220
+ const [user, setUser] = useState(null);
221
+
222
+ useEffect(() => {
223
+ fetch('/api/auth/session')
224
+ .then(res => res.json())
225
+ .then(data => setUser(data.session?.user ?? null));
226
+ }, []);
227
+
228
+ if (!user) return <a href="/login">Sign In</a>;
229
+
230
+ return (
231
+ <div>
232
+ <span>{user.name}</span>
233
+ <button onClick={() => {
234
+ fetch('/api/auth/logout', { method: 'POST' })
235
+ .then(() => window.location.href = '/');
236
+ }}>
237
+ Sign Out
238
+ </button>
239
+ </div>
240
+ );
241
+ }
242
+ ```
243
+
244
+ ## Login Page Pattern
245
+
246
+ ```typescript
247
+ 'use client';
248
+ import { useState } from 'react';
249
+ import { useRouter } from 'next/navigation';
250
+
251
+ export default function LoginPage() {
252
+ const [email, setEmail] = useState('');
253
+ const [password, setPassword] = useState('');
254
+ const [error, setError] = useState('');
255
+ const router = useRouter();
256
+
257
+ async function handleSubmit(e: React.FormEvent) {
258
+ e.preventDefault();
259
+ const res = await fetch('/api/auth/login', {
260
+ method: 'POST',
261
+ headers: { 'Content-Type': 'application/json' },
262
+ body: JSON.stringify({ email, password }),
263
+ });
264
+ if (res.ok) {
265
+ router.push('/');
266
+ router.refresh();
267
+ } else {
268
+ setError('Invalid email or password');
269
+ }
270
+ }
271
+
272
+ return (
273
+ <form onSubmit={handleSubmit}>
274
+ <input type="email" value={email} onChange={e => setEmail(e.target.value)} placeholder="Email" required />
275
+ <input type="password" value={password} onChange={e => setPassword(e.target.value)} placeholder="Password" required />
276
+ {error && <p style={{ color: 'red' }}>{error}</p>}
277
+ <button type="submit">Sign In</button>
278
+ </form>
279
+ );
280
+ }
281
+ ```
282
+
283
+ ## Seed Data for Scenarios
284
+
285
+ When creating scenarios with auth, include both `User` and `Session` rows in seed data:
286
+
287
+ ```json
288
+ {
289
+ "name": "Logged In User",
290
+ "type": "application",
291
+ "url": "/",
292
+ "seed": {
293
+ "user": [
294
+ {
295
+ "id": "user_1",
296
+ "name": "Alice",
297
+ "email": "alice@example.com",
298
+ "password": "password123"
299
+ }
300
+ ],
301
+ "session": [{ "id": "sess_1", "token": "sess_alice", "userId": "user_1" }]
302
+ },
303
+ "session": { "cookieValue": "sess_alice" }
304
+ }
305
+ ```
306
+
307
+ The top-level `"session"` field tells the proxy to set the `session-token` cookie,
308
+ auto-logging the user in when this scenario is active.
@@ -0,0 +1,304 @@
1
+ # Upgrading Auth for Production
2
+
3
+ The dev auth pattern in `app/lib/auth.ts` is designed for easy replacement.
4
+ All consumer code imports from `@/app/lib/auth` — only the internals of that file change.
5
+
6
+ ## What Stays the Same
7
+
8
+ Every file that imports from `@/app/lib/auth` continues to work unchanged:
9
+
10
+ - Server components calling `getSession()` and `requireAuth()`
11
+ - Client components fetching `/api/auth/session`
12
+ - API routes using `signIn()` and `signOut()`
13
+ - Login/logout forms
14
+
15
+ ## What Changes
16
+
17
+ Only `app/lib/auth.ts` internals. Replace the cookie+DB implementation with your chosen provider.
18
+
19
+ ---
20
+
21
+ ## NextAuth v5
22
+
23
+ ### Install
24
+
25
+ ```bash
26
+ npm install next-auth @auth/prisma-adapter
27
+ ```
28
+
29
+ ### Replace `app/lib/auth.ts`
30
+
31
+ ```typescript
32
+ import NextAuth from 'next-auth';
33
+ import { PrismaAdapter } from '@auth/prisma-adapter';
34
+ import { prisma } from '@/app/lib/prisma';
35
+ import Credentials from 'next-auth/providers/credentials';
36
+ // Add other providers: Google, GitHub, etc.
37
+
38
+ export interface AuthUser {
39
+ id: string;
40
+ name: string;
41
+ email: string;
42
+ image?: string | null;
43
+ }
44
+
45
+ export interface Session {
46
+ user: AuthUser;
47
+ }
48
+
49
+ const {
50
+ auth,
51
+ signIn: nextAuthSignIn,
52
+ signOut: nextAuthSignOut,
53
+ } = NextAuth({
54
+ adapter: PrismaAdapter(prisma),
55
+ providers: [
56
+ Credentials({
57
+ credentials: { email: {}, password: {} },
58
+ authorize: async (credentials) => {
59
+ const user = await prisma.user.findUnique({
60
+ where: { email: credentials.email as string },
61
+ });
62
+ if (!user) return null;
63
+ // In production, use bcrypt: await bcrypt.compare(password, user.password)
64
+ return user;
65
+ },
66
+ }),
67
+ // Add: Google({ clientId: ..., clientSecret: ... })
68
+ // Add: GitHub({ clientId: ..., clientSecret: ... })
69
+ ],
70
+ session: { strategy: 'jwt' },
71
+ });
72
+
73
+ export async function getSession(): Promise<Session | null> {
74
+ const session = await auth();
75
+ if (!session?.user) return null;
76
+ return {
77
+ user: {
78
+ id: session.user.id!,
79
+ name: session.user.name!,
80
+ email: session.user.email!,
81
+ image: session.user.image,
82
+ },
83
+ };
84
+ }
85
+
86
+ export async function requireAuth(): Promise<Session> {
87
+ const session = await getSession();
88
+ if (!session) {
89
+ const { redirect } = await import('next/navigation');
90
+ redirect('/login');
91
+ }
92
+ return session;
93
+ }
94
+
95
+ export async function signIn(
96
+ email: string,
97
+ password: string,
98
+ ): Promise<Session | null> {
99
+ try {
100
+ await nextAuthSignIn('credentials', { email, password, redirect: false });
101
+ return getSession();
102
+ } catch {
103
+ return null;
104
+ }
105
+ }
106
+
107
+ export async function signOut(): Promise<void> {
108
+ await nextAuthSignOut({ redirect: false });
109
+ }
110
+ ```
111
+
112
+ ### Add route handler
113
+
114
+ Create `app/api/auth/[...nextauth]/route.ts`:
115
+
116
+ ```typescript
117
+ import { handlers } from '@/app/lib/auth';
118
+ export const { GET, POST } = handlers;
119
+ ```
120
+
121
+ ---
122
+
123
+ ## better-auth
124
+
125
+ ### Install
126
+
127
+ ```bash
128
+ npm install better-auth
129
+ ```
130
+
131
+ ### Replace `app/lib/auth.ts`
132
+
133
+ ```typescript
134
+ import { betterAuth } from 'better-auth';
135
+ import { prismaAdapter } from 'better-auth/adapters/prisma';
136
+ import { prisma } from '@/app/lib/prisma';
137
+ import { cookies } from 'next/headers';
138
+
139
+ export interface AuthUser {
140
+ id: string;
141
+ name: string;
142
+ email: string;
143
+ image?: string | null;
144
+ }
145
+
146
+ export interface Session {
147
+ user: AuthUser;
148
+ }
149
+
150
+ const auth = betterAuth({
151
+ database: prismaAdapter(prisma, { provider: 'sqlite' }),
152
+ emailAndPassword: { enabled: true },
153
+ });
154
+
155
+ export async function getSession(): Promise<Session | null> {
156
+ const cookieStore = await cookies();
157
+ const session = await auth.api.getSession({
158
+ headers: new Headers({ cookie: cookieStore.toString() }),
159
+ });
160
+ if (!session?.user) return null;
161
+ return {
162
+ user: {
163
+ id: session.user.id,
164
+ name: session.user.name,
165
+ email: session.user.email,
166
+ image: session.user.image ?? null,
167
+ },
168
+ };
169
+ }
170
+
171
+ export async function requireAuth(): Promise<Session> {
172
+ const session = await getSession();
173
+ if (!session) {
174
+ const { redirect } = await import('next/navigation');
175
+ redirect('/login');
176
+ }
177
+ return session;
178
+ }
179
+
180
+ export async function signIn(
181
+ email: string,
182
+ password: string,
183
+ ): Promise<Session | null> {
184
+ try {
185
+ await auth.api.signInEmail({ body: { email, password } });
186
+ return getSession();
187
+ } catch {
188
+ return null;
189
+ }
190
+ }
191
+
192
+ export async function signOut(): Promise<void> {
193
+ const cookieStore = await cookies();
194
+ await auth.api.signOut({
195
+ headers: new Headers({ cookie: cookieStore.toString() }),
196
+ });
197
+ }
198
+ ```
199
+
200
+ ---
201
+
202
+ ## Supabase Auth
203
+
204
+ ### Install
205
+
206
+ ```bash
207
+ npm install @supabase/supabase-js @supabase/ssr
208
+ ```
209
+
210
+ ### Replace `app/lib/auth.ts`
211
+
212
+ ```typescript
213
+ import { createServerClient } from '@supabase/ssr';
214
+ import { cookies } from 'next/headers';
215
+
216
+ export interface AuthUser {
217
+ id: string;
218
+ name: string;
219
+ email: string;
220
+ image?: string | null;
221
+ }
222
+
223
+ export interface Session {
224
+ user: AuthUser;
225
+ }
226
+
227
+ function createClient() {
228
+ const cookieStore = cookies();
229
+ return createServerClient(
230
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
231
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
232
+ {
233
+ cookies: {
234
+ getAll: () => cookieStore.then((c) => c.getAll()),
235
+ setAll: (cookies) =>
236
+ cookieStore.then((c) => {
237
+ cookies.forEach(({ name, value, options }) =>
238
+ c.set(name, value, options),
239
+ );
240
+ }),
241
+ },
242
+ },
243
+ );
244
+ }
245
+
246
+ export async function getSession(): Promise<Session | null> {
247
+ const supabase = createClient();
248
+ const {
249
+ data: { user },
250
+ } = await supabase.auth.getUser();
251
+ if (!user) return null;
252
+ return {
253
+ user: {
254
+ id: user.id,
255
+ name: user.user_metadata.name || user.email?.split('@')[0] || '',
256
+ email: user.email!,
257
+ image: user.user_metadata.avatar_url ?? null,
258
+ },
259
+ };
260
+ }
261
+
262
+ export async function requireAuth(): Promise<Session> {
263
+ const session = await getSession();
264
+ if (!session) {
265
+ const { redirect } = await import('next/navigation');
266
+ redirect('/login');
267
+ }
268
+ return session;
269
+ }
270
+
271
+ export async function signIn(
272
+ email: string,
273
+ password: string,
274
+ ): Promise<Session | null> {
275
+ const supabase = createClient();
276
+ const { error } = await supabase.auth.signInWithPassword({ email, password });
277
+ if (error) return null;
278
+ return getSession();
279
+ }
280
+
281
+ export async function signOut(): Promise<void> {
282
+ const supabase = createClient();
283
+ await supabase.auth.signOut();
284
+ }
285
+ ```
286
+
287
+ ### Environment variables
288
+
289
+ Add to `.env.local`:
290
+
291
+ ```
292
+ NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
293
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
294
+ ```
295
+
296
+ ---
297
+
298
+ ## After Upgrading
299
+
300
+ 1. Remove the `Session` model from `prisma/schema.prisma` (the provider manages sessions)
301
+ 2. Keep the `User` model if your provider uses it, or migrate to the provider's user table
302
+ 3. Run `npm run db:push` to apply schema changes
303
+ 4. Test sign-in and sign-out flows
304
+ 5. Update scenario seed data if the session table structure changed