@codeyam/codeyam-cli 0.1.0-staging.8df382d → 0.1.0-staging.a890816

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 (331) hide show
  1. package/analyzer-template/.build-info.json +7 -7
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +34 -3
  4. package/analyzer-template/packages/ai/src/lib/completionCall.ts +14 -2
  5. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +27 -0
  6. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/coercePrimitivesToArraysBySchema.ts +62 -0
  7. package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +78 -2
  8. package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +6 -0
  9. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +9 -1
  10. package/analyzer-template/packages/analyze/src/lib/files/analyze/dependencyResolver.ts +0 -6
  11. package/analyzer-template/packages/analyze/src/lib/files/analyze/findOrCreateEntity.ts +12 -0
  12. package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +65 -28
  13. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +83 -0
  14. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +23 -4
  15. package/analyzer-template/packages/database/index.ts +1 -0
  16. package/analyzer-template/packages/database/src/lib/kysely/db.ts +8 -0
  17. package/analyzer-template/packages/database/src/lib/kysely/tables/editorScenariosTable.ts +62 -0
  18. package/analyzer-template/packages/database/src/lib/loadCommits.ts +31 -20
  19. package/analyzer-template/packages/database/src/lib/loadReadyToBeCapturedAnalyses.ts +0 -5
  20. package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +151 -135
  21. package/analyzer-template/packages/database/src/lib/updateFreshAnalysisStatus.ts +58 -42
  22. package/analyzer-template/packages/database/src/lib/updateFreshAnalysisStatusWithScenarios.ts +81 -65
  23. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.ts +29 -1
  24. package/analyzer-template/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.ts +33 -5
  25. package/analyzer-template/packages/github/dist/database/index.d.ts +1 -0
  26. package/analyzer-template/packages/github/dist/database/index.d.ts.map +1 -1
  27. package/analyzer-template/packages/github/dist/database/index.js +1 -0
  28. package/analyzer-template/packages/github/dist/database/index.js.map +1 -1
  29. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts +2 -0
  30. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
  31. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +5 -0
  32. package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
  33. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts +20 -0
  34. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts.map +1 -0
  35. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js +45 -0
  36. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -0
  37. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts +5 -0
  38. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/scenariosTable.d.ts.map +1 -1
  39. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts.map +1 -1
  40. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js +23 -13
  41. package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js.map +1 -1
  42. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.d.ts.map +1 -1
  43. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js +1 -4
  44. package/analyzer-template/packages/github/dist/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
  45. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
  46. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +100 -89
  47. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js.map +1 -1
  48. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatus.d.ts.map +1 -1
  49. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatus.js +41 -30
  50. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatus.js.map +1 -1
  51. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatusWithScenarios.d.ts.map +1 -1
  52. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatusWithScenarios.js +68 -57
  53. package/analyzer-template/packages/github/dist/database/src/lib/updateFreshAnalysisStatusWithScenarios.js.map +1 -1
  54. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.d.ts.map +1 -1
  55. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js +29 -1
  56. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js.map +1 -1
  57. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.d.ts.map +1 -1
  58. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +33 -5
  59. package/analyzer-template/packages/github/dist/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
  60. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts +1 -0
  61. package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  62. package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts +10 -0
  63. package/analyzer-template/packages/github/dist/types/src/types/Scenario.d.ts.map +1 -1
  64. package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +1 -0
  65. package/analyzer-template/packages/types/src/types/Scenario.ts +10 -0
  66. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts +1 -0
  67. package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
  68. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts +10 -0
  69. package/analyzer-template/packages/utils/dist/types/src/types/Scenario.d.ts.map +1 -1
  70. package/analyzer-template/playwright/captureFromUrl.ts +89 -82
  71. package/analyzer-template/project/constructMockCode.ts +136 -43
  72. package/analyzer-template/project/reconcileMockDataKeys.ts +19 -14
  73. package/analyzer-template/project/start.ts +3 -0
  74. package/analyzer-template/project/startScenarioCapture.ts +9 -0
  75. package/analyzer-template/project/writeClientLogRoute.ts +125 -0
  76. package/analyzer-template/project/writeMockDataTsx.ts +17 -0
  77. package/analyzer-template/project/writeScenarioComponents.ts +36 -7
  78. package/analyzer-template/tsconfig.json +13 -1
  79. package/background/src/lib/virtualized/project/constructMockCode.js +115 -34
  80. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  81. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +17 -11
  82. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
  83. package/background/src/lib/virtualized/project/start.js +2 -0
  84. package/background/src/lib/virtualized/project/start.js.map +1 -1
  85. package/background/src/lib/virtualized/project/startScenarioCapture.js +5 -0
  86. package/background/src/lib/virtualized/project/startScenarioCapture.js.map +1 -1
  87. package/background/src/lib/virtualized/project/writeClientLogRoute.js +110 -0
  88. package/background/src/lib/virtualized/project/writeClientLogRoute.js.map +1 -0
  89. package/background/src/lib/virtualized/project/writeMockDataTsx.js +12 -0
  90. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  91. package/background/src/lib/virtualized/project/writeScenarioComponents.js +29 -7
  92. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  93. package/codeyam-cli/scripts/apply-setup.js +208 -11
  94. package/codeyam-cli/scripts/apply-setup.js.map +1 -1
  95. package/codeyam-cli/src/cli.js +2 -0
  96. package/codeyam-cli/src/cli.js.map +1 -1
  97. package/codeyam-cli/src/commands/analyze.js +17 -7
  98. package/codeyam-cli/src/commands/analyze.js.map +1 -1
  99. package/codeyam-cli/src/commands/default.js +58 -3
  100. package/codeyam-cli/src/commands/default.js.map +1 -1
  101. package/codeyam-cli/src/commands/editor.js +1037 -0
  102. package/codeyam-cli/src/commands/editor.js.map +1 -0
  103. package/codeyam-cli/src/commands/init.js +34 -10
  104. package/codeyam-cli/src/commands/init.js.map +1 -1
  105. package/codeyam-cli/src/commands/memory.js +26 -2
  106. package/codeyam-cli/src/commands/memory.js.map +1 -1
  107. package/codeyam-cli/src/utils/__tests__/pathIgnoring.test.js +9 -0
  108. package/codeyam-cli/src/utils/__tests__/pathIgnoring.test.js.map +1 -1
  109. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +26 -0
  110. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  111. package/codeyam-cli/src/utils/backgroundServer.js +19 -3
  112. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  113. package/codeyam-cli/src/utils/devModeEvents.js +40 -0
  114. package/codeyam-cli/src/utils/devModeEvents.js.map +1 -0
  115. package/codeyam-cli/src/utils/fileMetadata.js +5 -0
  116. package/codeyam-cli/src/utils/fileMetadata.js.map +1 -1
  117. package/codeyam-cli/src/utils/fileWatcher.js +25 -9
  118. package/codeyam-cli/src/utils/fileWatcher.js.map +1 -1
  119. package/codeyam-cli/src/utils/git.js +52 -0
  120. package/codeyam-cli/src/utils/git.js.map +1 -1
  121. package/codeyam-cli/src/utils/install-skills.js +31 -0
  122. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  123. package/codeyam-cli/src/utils/interactiveSyncWatcher.js +126 -0
  124. package/codeyam-cli/src/utils/interactiveSyncWatcher.js.map +1 -0
  125. package/codeyam-cli/src/utils/pathIgnoring.js +19 -7
  126. package/codeyam-cli/src/utils/pathIgnoring.js.map +1 -1
  127. package/codeyam-cli/src/utils/queue/__tests__/heartbeat.test.js +11 -11
  128. package/codeyam-cli/src/utils/queue/__tests__/heartbeat.test.js.map +1 -1
  129. package/codeyam-cli/src/utils/queue/__tests__/manager.test.js +22 -0
  130. package/codeyam-cli/src/utils/queue/__tests__/manager.test.js.map +1 -1
  131. package/codeyam-cli/src/utils/queue/heartbeat.js +13 -5
  132. package/codeyam-cli/src/utils/queue/heartbeat.js.map +1 -1
  133. package/codeyam-cli/src/utils/queue/job.js +70 -1
  134. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  135. package/codeyam-cli/src/utils/queue/manager.js +7 -6
  136. package/codeyam-cli/src/utils/queue/manager.js.map +1 -1
  137. package/codeyam-cli/src/utils/serverState.js +27 -2
  138. package/codeyam-cli/src/utils/serverState.js.map +1 -1
  139. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +45 -4
  140. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  141. package/codeyam-cli/src/utils/testRunner.js +158 -0
  142. package/codeyam-cli/src/utils/testRunner.js.map +1 -0
  143. package/codeyam-cli/src/utils/transcriptPruning.js +67 -0
  144. package/codeyam-cli/src/utils/transcriptPruning.js.map +1 -0
  145. package/codeyam-cli/src/utils/webappDetection.js +14 -2
  146. package/codeyam-cli/src/utils/webappDetection.js.map +1 -1
  147. package/codeyam-cli/src/webserver/app/lib/database.js +41 -27
  148. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  149. package/codeyam-cli/src/webserver/app/lib/dbNotifier.js.map +1 -1
  150. package/codeyam-cli/src/webserver/backgroundServer.js +109 -19
  151. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  152. package/codeyam-cli/src/webserver/build/client/assets/{CopyButton-CtmbP4Gl.js → CopyButton-DmJveP3T.js} +1 -1
  153. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-DlMph_Hm.js → EntityItem-C76mRRiF.js} +1 -1
  154. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-B-0PjGOU.js → EntityTypeBadge-g3saevPb.js} +1 -1
  155. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-DN9eiJAO.js → EntityTypeIcon-CobE682z.js} +1 -1
  156. package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-Bu6c6aDe.js +1 -0
  157. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-rE_fI2h2.js → InteractivePreview-DYFW3lDD.js} +3 -3
  158. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-CnatsCw2.js → LibraryFunctionPreview-DLeucoVX.js} +1 -1
  159. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-CSP6DZrh.js → LoadingDots-BU_OAEMP.js} +1 -1
  160. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-CMK8Q7yk.js → LogViewer-ceAyBX-H.js} +1 -1
  161. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-TCV_HBjy.js → ReportIssueModal-djPLI-WV.js} +1 -1
  162. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-CG2uh31y.js → SafeScreenshot-BED4B6sP.js} +1 -1
  163. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-CU_TDYd8.js → ScenarioViewer-B76aig_2.js} +1 -1
  164. package/codeyam-cli/src/webserver/build/client/assets/Spinner-Bb5uFQ5V.js +34 -0
  165. package/codeyam-cli/src/webserver/build/client/assets/Terminal-CcG8YTLx.js +41 -0
  166. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-D7IoaWUW.js → TruncatedFilePath-C8OKAR5x.js} +1 -1
  167. package/codeyam-cli/src/webserver/build/client/assets/{_index-B8z7mjR-.js → _index-C96V0n15.js} +1 -1
  168. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-DZu78RI1.js → activity.(_tab)-BpKzcsJz.js} +1 -1
  169. package/codeyam-cli/src/webserver/build/client/assets/addon-fit-CUXOrorO.js +1 -0
  170. package/codeyam-cli/src/webserver/build/client/assets/addon-web-links-Duc5hnl7.js +1 -0
  171. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-D9hemwl6.js +22 -0
  172. package/codeyam-cli/src/webserver/build/client/assets/api.dev-mode-events-l0sNRNKZ.js +1 -0
  173. package/codeyam-cli/src/webserver/build/client/assets/api.editor-capture-scenario-l0sNRNKZ.js +1 -0
  174. package/codeyam-cli/src/webserver/build/client/assets/api.editor-client-errors-l0sNRNKZ.js +1 -0
  175. package/codeyam-cli/src/webserver/build/client/assets/api.editor-commit-l0sNRNKZ.js +1 -0
  176. package/codeyam-cli/src/webserver/build/client/assets/api.editor-dev-server-l0sNRNKZ.js +1 -0
  177. package/codeyam-cli/src/webserver/build/client/assets/api.editor-entity-status-l0sNRNKZ.js +1 -0
  178. package/codeyam-cli/src/webserver/build/client/assets/api.editor-journal-entry-l0sNRNKZ.js +1 -0
  179. package/codeyam-cli/src/webserver/build/client/assets/api.editor-journal-image._-l0sNRNKZ.js +1 -0
  180. package/codeyam-cli/src/webserver/build/client/assets/api.editor-journal-l0sNRNKZ.js +1 -0
  181. package/codeyam-cli/src/webserver/build/client/assets/api.editor-journal-screenshot-l0sNRNKZ.js +1 -0
  182. package/codeyam-cli/src/webserver/build/client/assets/api.editor-journal-update-l0sNRNKZ.js +1 -0
  183. package/codeyam-cli/src/webserver/build/client/assets/api.editor-refresh-l0sNRNKZ.js +1 -0
  184. package/codeyam-cli/src/webserver/build/client/assets/api.editor-register-scenario-l0sNRNKZ.js +1 -0
  185. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-data-l0sNRNKZ.js +1 -0
  186. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-image._-l0sNRNKZ.js +1 -0
  187. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenarios-l0sNRNKZ.js +1 -0
  188. package/codeyam-cli/src/webserver/build/client/assets/api.editor-switch-scenario-l0sNRNKZ.js +1 -0
  189. package/codeyam-cli/src/webserver/build/client/assets/api.editor-test-results-l0sNRNKZ.js +1 -0
  190. package/codeyam-cli/src/webserver/build/client/assets/{book-open-Bp5FLkd4.js → book-open-D_nMCFmP.js} +1 -1
  191. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-DQJA9f4o.js → chevron-down-BH2h1Ea2.js} +1 -1
  192. package/codeyam-cli/src/webserver/build/client/assets/{chunk-JZWAC4HX-7VptmeIr.js → chunk-JZWAC4HX-C4pqxYJB.js} +1 -1
  193. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-B6C4LY9o.js → circle-check-DyIKORY6.js} +1 -1
  194. package/codeyam-cli/src/webserver/build/client/assets/{copy-6nzYCu0G.js → copy-NDbZjXao.js} +1 -1
  195. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-D-QUFOwe.js → createLucideIcon-CMT1jU2q.js} +1 -1
  196. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BiM6z3Do.js +1 -0
  197. package/codeyam-cli/src/webserver/build/client/assets/editor-W_IGJ2Kd.js +7 -0
  198. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._--zvFJ4OH.js → entity._sha._-CrjR3zZW.js} +10 -10
  199. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-D6SEzMCu.js +6 -0
  200. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-C28BiQzt.js +6 -0
  201. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-p9hhkjJM.js +6 -0
  202. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-C7ysA4Jq.js → entity._sha_.edit._scenarioId-BMvVHNXU.js} +2 -2
  203. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-CU6EUArK.js → entry.client-DTvKq3TY.js} +1 -1
  204. package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-EWpfFU4X.js → fileTableUtils-cPo8LiG3.js} +1 -1
  205. package/codeyam-cli/src/webserver/build/client/assets/{files-CrxAoWIL.js → files-DO4CZ16O.js} +1 -1
  206. package/codeyam-cli/src/webserver/build/client/assets/{git-BldHtKeW.js → git-CFCTYk9I.js} +1 -1
  207. package/codeyam-cli/src/webserver/build/client/assets/globals-BZB_H1w2.css +1 -0
  208. package/codeyam-cli/src/webserver/build/client/assets/{index-7-1FmlHo.js → index-10oVnAAH.js} +1 -1
  209. package/codeyam-cli/src/webserver/build/client/assets/{index-DuYcwYp_.js → index-BcvgDzbZ.js} +1 -1
  210. package/codeyam-cli/src/webserver/build/client/assets/{labs-CPPVOSWB.js → labs-Zk7ryIM1.js} +1 -1
  211. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-BnDcD54R.js → loader-circle-BAXYRVEO.js} +1 -1
  212. package/codeyam-cli/src/webserver/build/client/assets/manifest-8daa4147.js +1 -0
  213. package/codeyam-cli/src/webserver/build/client/assets/{memory-CfpYxpNu.js → memory-FweZHj5U.js} +28 -28
  214. package/codeyam-cli/src/webserver/build/client/assets/{pause-DhQX2g22.js → pause-DTAcYxBt.js} +1 -1
  215. package/codeyam-cli/src/webserver/build/client/assets/root-DiRdBreB.js +67 -0
  216. package/codeyam-cli/src/webserver/build/client/assets/{search-DborVoKD.js → search-fKo7v0Zo.js} +1 -1
  217. package/codeyam-cli/src/webserver/build/client/assets/settings-DfuTtcJP.js +1 -0
  218. package/codeyam-cli/src/webserver/build/client/assets/{simulations-BtrtCYJg.js → simulations-B3aOzpCZ.js} +1 -1
  219. package/codeyam-cli/src/webserver/build/client/assets/{terminal-Bs4NC-VZ.js → terminal-BG4heKCG.js} +1 -1
  220. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-DTf3Jojp.js → triangle-alert-DtSmdtM4.js} +1 -1
  221. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-D_bDZyDU.js → useCustomSizes-ByhSyh0W.js} +1 -1
  222. package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-C14nCb1q.js +2 -0
  223. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-BsQb6rFd.js → useReportContext-O-jkvSPx.js} +1 -1
  224. package/codeyam-cli/src/webserver/build/client/assets/{useToast-BOur3mUv.js → useToast-9FIWuYfK.js} +1 -1
  225. package/codeyam-cli/src/webserver/build/client/assets/xterm-DMSzMhqy.js +9 -0
  226. package/codeyam-cli/src/webserver/build/server/assets/index-BzAbACSx.js +1 -0
  227. package/codeyam-cli/src/webserver/build/server/assets/server-build-OdUocH6P.js +362 -0
  228. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  229. package/codeyam-cli/src/webserver/build-info.json +5 -5
  230. package/codeyam-cli/src/webserver/devServer.js +39 -5
  231. package/codeyam-cli/src/webserver/devServer.js.map +1 -1
  232. package/codeyam-cli/src/webserver/editorProxy.js +272 -0
  233. package/codeyam-cli/src/webserver/editorProxy.js.map +1 -0
  234. package/codeyam-cli/src/webserver/scripts/journalCapture.ts +140 -0
  235. package/codeyam-cli/src/webserver/server.js +177 -1
  236. package/codeyam-cli/src/webserver/server.js.map +1 -1
  237. package/codeyam-cli/src/webserver/terminalServer.js +753 -0
  238. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -0
  239. package/codeyam-cli/templates/codeyam-dev-mode.md +237 -0
  240. package/codeyam-cli/templates/codeyam-editor-claude.md +68 -0
  241. package/codeyam-cli/templates/codeyam-editor.md +68 -0
  242. package/codeyam-cli/templates/editor-step-hook.py +145 -0
  243. package/codeyam-cli/templates/isolation-route/next-app.tsx.template +80 -0
  244. package/codeyam-cli/templates/isolation-route/next-pages.tsx.template +79 -0
  245. package/codeyam-cli/templates/isolation-route/vite-react.tsx.template +78 -0
  246. package/codeyam-cli/templates/msw/browser-setup.ts.template +47 -0
  247. package/codeyam-cli/templates/msw/handler-router.ts.template +47 -0
  248. package/codeyam-cli/templates/msw/server-setup.ts.template +52 -0
  249. package/codeyam-cli/templates/nextjs-prisma-sqlite/PRISMA_SETUP.md +84 -0
  250. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/api/todos/route.ts +17 -0
  251. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/globals.css +26 -0
  252. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/layout.tsx +34 -0
  253. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/lib/prisma.ts +19 -0
  254. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/page.tsx +10 -0
  255. package/codeyam-cli/templates/nextjs-prisma-sqlite/eslint.config.mjs +11 -0
  256. package/codeyam-cli/templates/nextjs-prisma-sqlite/gitignore +43 -0
  257. package/codeyam-cli/templates/nextjs-prisma-sqlite/next.config.ts +14 -0
  258. package/codeyam-cli/templates/nextjs-prisma-sqlite/package.json +35 -0
  259. package/codeyam-cli/templates/nextjs-prisma-sqlite/postcss.config.mjs +7 -0
  260. package/codeyam-cli/templates/nextjs-prisma-sqlite/prisma/schema.prisma +27 -0
  261. package/codeyam-cli/templates/nextjs-prisma-sqlite/prisma/seed.ts +37 -0
  262. package/codeyam-cli/templates/nextjs-prisma-sqlite/prisma.config.ts +12 -0
  263. package/codeyam-cli/templates/nextjs-prisma-sqlite/tsconfig.json +34 -0
  264. package/codeyam-cli/templates/prompts/conversation-guidance.txt +12 -0
  265. package/codeyam-cli/templates/prompts/conversation-prompt.txt +3 -3
  266. package/codeyam-cli/templates/prompts/interruption-prompt.txt +3 -3
  267. package/codeyam-cli/templates/prompts/stale-rules-prompt.txt +3 -3
  268. package/codeyam-cli/templates/rule-notification-hook.py +44 -17
  269. package/codeyam-cli/templates/rule-reflection-hook.py +24 -4
  270. package/codeyam-cli/templates/rules-instructions.md +4 -3
  271. package/package.json +4 -2
  272. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +22 -4
  273. package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
  274. package/packages/ai/src/lib/completionCall.js +10 -2
  275. package/packages/ai/src/lib/completionCall.js.map +1 -1
  276. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +21 -0
  277. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  278. package/packages/ai/src/lib/dataStructure/helpers/coercePrimitivesToArraysBySchema.js +54 -0
  279. package/packages/ai/src/lib/dataStructure/helpers/coercePrimitivesToArraysBySchema.js.map +1 -0
  280. package/packages/ai/src/lib/dataStructure/helpers/stripNullableMarkers.js +34 -0
  281. package/packages/ai/src/lib/dataStructure/helpers/stripNullableMarkers.js.map +1 -0
  282. package/packages/ai/src/lib/generateEntityScenarioData.js +57 -2
  283. package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
  284. package/packages/analyze/src/lib/ProjectAnalyzer.js +3 -0
  285. package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
  286. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +8 -1
  287. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  288. package/packages/analyze/src/lib/files/analyze/dependencyResolver.js +0 -5
  289. package/packages/analyze/src/lib/files/analyze/dependencyResolver.js.map +1 -1
  290. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js +9 -0
  291. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js.map +1 -1
  292. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +54 -27
  293. package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -1
  294. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +65 -0
  295. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  296. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +18 -4
  297. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  298. package/packages/database/index.js +1 -0
  299. package/packages/database/index.js.map +1 -1
  300. package/packages/database/src/lib/kysely/db.js +5 -0
  301. package/packages/database/src/lib/kysely/db.js.map +1 -1
  302. package/packages/database/src/lib/kysely/tables/editorScenariosTable.js +45 -0
  303. package/packages/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -0
  304. package/packages/database/src/lib/loadCommits.js +23 -13
  305. package/packages/database/src/lib/loadCommits.js.map +1 -1
  306. package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js +1 -4
  307. package/packages/database/src/lib/loadReadyToBeCapturedAnalyses.js.map +1 -1
  308. package/packages/database/src/lib/updateCommitMetadata.js +100 -89
  309. package/packages/database/src/lib/updateCommitMetadata.js.map +1 -1
  310. package/packages/database/src/lib/updateFreshAnalysisStatus.js +41 -30
  311. package/packages/database/src/lib/updateFreshAnalysisStatus.js.map +1 -1
  312. package/packages/database/src/lib/updateFreshAnalysisStatusWithScenarios.js +68 -57
  313. package/packages/database/src/lib/updateFreshAnalysisStatusWithScenarios.js.map +1 -1
  314. package/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js +29 -1
  315. package/packages/generate/src/lib/componentScenarioPage/generateScenarioClientWrapper.js.map +1 -1
  316. package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js +33 -5
  317. package/packages/generate/src/lib/componentScenarioPage/getIFrameMessageListenerCode.js.map +1 -1
  318. package/codeyam-cli/src/webserver/app/routes/api.agent-transcripts.js +0 -486
  319. package/codeyam-cli/src/webserver/app/routes/api.agent-transcripts.js.map +0 -1
  320. package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-C1rIyZdV.js +0 -34
  321. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-DxCa1oBt.js +0 -23
  322. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DmzSmblj.js +0 -1
  323. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-DVTcUnur.js +0 -6
  324. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-BVgNO76F.js +0 -6
  325. package/codeyam-cli/src/webserver/build/client/assets/globals-B4MPiL7S.css +0 -1
  326. package/codeyam-cli/src/webserver/build/client/assets/manifest-c1fc3656.js +0 -1
  327. package/codeyam-cli/src/webserver/build/client/assets/root-CAAbm4U5.js +0 -62
  328. package/codeyam-cli/src/webserver/build/client/assets/settings-BpLDWmGh.js +0 -1
  329. package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-DZp6rrQD.js +0 -2
  330. package/codeyam-cli/src/webserver/build/server/assets/index-B8A_aaGG.js +0 -1
  331. package/codeyam-cli/src/webserver/build/server/assets/server-build-69rRZnZo.js +0 -286
@@ -0,0 +1,1037 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import chalk from 'chalk';
5
+ import { runAnalysisForEntities } from "../utils/analysisRunner.js";
6
+ import { ProgressReporter } from "../utils/progress.js";
7
+ import { initializeEnvironment } from "../utils/database.js";
8
+ import { loadEntities, loadAnalyses } from "../../../packages/database/index.js";
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+ const STEP_LABELS = {
12
+ 1: 'Plan',
13
+ 2: 'Prototype',
14
+ 3: 'Confirm',
15
+ 4: 'Deconstruct',
16
+ 5: 'Extract',
17
+ 6: 'Glossary',
18
+ 7: 'Analyze',
19
+ 8: 'App Scenarios',
20
+ 9: 'User Scenarios',
21
+ 10: 'Verify',
22
+ 11: 'Review',
23
+ };
24
+ /**
25
+ * Append a JSONL log entry to .codeyam/logs/editor-log.jsonl
26
+ */
27
+ function logEvent(root, event, data) {
28
+ try {
29
+ const logsDir = path.join(root, '.codeyam', 'logs');
30
+ fs.mkdirSync(logsDir, { recursive: true });
31
+ const logPath = path.join(logsDir, 'editor-log.jsonl');
32
+ const entry = JSON.stringify({
33
+ ts: new Date().toISOString(),
34
+ event,
35
+ ...data,
36
+ });
37
+ fs.appendFileSync(logPath, entry + '\n', 'utf8');
38
+ }
39
+ catch {
40
+ // Logging is best-effort
41
+ }
42
+ }
43
+ /**
44
+ * Get the project root (where .codeyam/ lives) or cwd.
45
+ */
46
+ function getProjectRoot() {
47
+ return process.env.CODEYAM_ROOT_PATH || process.cwd();
48
+ }
49
+ /**
50
+ * Path to the editor step state file.
51
+ */
52
+ function getStatePath(root) {
53
+ return path.join(root, '.codeyam', 'editor-step.json');
54
+ }
55
+ /**
56
+ * Read the current editor state, or null if none.
57
+ */
58
+ function readState(root) {
59
+ const statePath = getStatePath(root);
60
+ try {
61
+ const content = fs.readFileSync(statePath, 'utf8');
62
+ return JSON.parse(content);
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
68
+ /**
69
+ * Write the editor state.
70
+ */
71
+ function writeState(root, state) {
72
+ const statePath = getStatePath(root);
73
+ const dir = path.dirname(statePath);
74
+ fs.mkdirSync(dir, { recursive: true });
75
+ fs.writeFileSync(statePath, JSON.stringify(state, null, 2), 'utf8');
76
+ }
77
+ /**
78
+ * Clear the editor state (for starting a new feature).
79
+ */
80
+ function clearState(root) {
81
+ const statePath = getStatePath(root);
82
+ try {
83
+ fs.unlinkSync(statePath);
84
+ }
85
+ catch {
86
+ // File doesn't exist, that's fine
87
+ }
88
+ }
89
+ /**
90
+ * Check if a project has been scaffolded (package.json exists).
91
+ */
92
+ function hasProject(root) {
93
+ return fs.existsSync(path.join(root, 'package.json'));
94
+ }
95
+ /**
96
+ * Get the CodeYam server port from env or default.
97
+ */
98
+ function getServerPort() {
99
+ return process.env.CODEYAM_PORT || '3111';
100
+ }
101
+ /**
102
+ * Print a checklist item.
103
+ * Inline backtick-wrapped text is highlighted in cyan for visibility.
104
+ */
105
+ function checkbox(text) {
106
+ // Highlight `backtick-wrapped` segments in cyan
107
+ const highlighted = text.replace(/`([^`]+)`/g, (_m, code) => chalk.cyan(code));
108
+ console.log(` ${chalk.dim('[ ]')} ${highlighted}`);
109
+ }
110
+ /**
111
+ * Print a section header.
112
+ */
113
+ function stepHeader(step, title, feature) {
114
+ console.log();
115
+ console.log(chalk.bold.cyan(`━━━ Step ${step}: ${title} ━━━`));
116
+ if (feature) {
117
+ console.log(chalk.dim(`Feature: "${feature}"`));
118
+ }
119
+ console.log();
120
+ }
121
+ /**
122
+ * Print a colored progress tracker showing all 11 steps.
123
+ * Steps before `current` are green ✓, `current` is bold cyan →, future steps are dim ○.
124
+ */
125
+ function printProgressTracker(current) {
126
+ console.log();
127
+ console.log(chalk.dim('┌─────────────────────────────────────┐'));
128
+ for (let i = 1; i <= 11; i++) {
129
+ const label = STEP_LABELS[i];
130
+ const num = i < 10 ? ` ${i}` : `${i}`;
131
+ const content = `${num}. ${label.padEnd(28)}`;
132
+ if (i < current) {
133
+ console.log(chalk.dim(' │') + chalk.green(` ✓ ${content}`) + chalk.dim('│'));
134
+ }
135
+ else if (i === current) {
136
+ console.log(chalk.dim(' │') + chalk.bold.cyan(` → ${content}`) + chalk.dim('│'));
137
+ }
138
+ else {
139
+ console.log(chalk.dim(` │ ○ ${content}│`));
140
+ }
141
+ }
142
+ console.log(chalk.dim(' └─────────────────────────────────────┘'));
143
+ }
144
+ /**
145
+ * Print a hard STOP gate directing to the next command.
146
+ *
147
+ * Options:
148
+ * - confirm: true → step requires user confirmation before proceeding (steps 1, 3, 11)
149
+ */
150
+ function stopGate(current, opts) {
151
+ console.log();
152
+ console.log(chalk.bold.red('━━━ STOP ━━━'));
153
+ console.log();
154
+ console.log(chalk.red('Complete each checklist item above before proceeding to the next step.'));
155
+ if (opts?.confirm) {
156
+ console.log();
157
+ console.log(chalk.yellow('Wait for user confirmation before moving on.'));
158
+ }
159
+ console.log();
160
+ console.log(chalk.bold.yellow('Present the following progress tracker to the user (copy it verbatim):'));
161
+ printProgressTracker(current);
162
+ console.log();
163
+ console.log(chalk.yellow('For the CURRENT step (→), show each checklist item with ✓ (done) or ✗ (skipped + reason).'));
164
+ console.log(chalk.yellow('If any items are ✗, explain why and ask if the user wants to address them.'));
165
+ console.log();
166
+ if (current < 10) {
167
+ console.log(chalk.green('When done, run: ') +
168
+ chalk.bold(`codeyam editor ${current + 1}`));
169
+ }
170
+ else {
171
+ console.log(chalk.green('Feature complete! Run: ') +
172
+ chalk.bold('codeyam editor 1') +
173
+ chalk.green(' to start the next feature'));
174
+ }
175
+ console.log();
176
+ }
177
+ // ─── Setup (no args, no project) ──────────────────────────────────────
178
+ function printSetup(root) {
179
+ const port = getServerPort();
180
+ logEvent(root, 'setup');
181
+ console.log();
182
+ console.log(chalk.bold.cyan('━━━ Editor Mode: Project Setup ━━━'));
183
+ console.log();
184
+ console.log("No project detected. Let's get started.");
185
+ console.log();
186
+ console.log(chalk.bold('Checklist:'));
187
+ checkbox('Read `.codeyam/editor-mode-context.md` for session state');
188
+ checkbox('Ask the user what they want to build');
189
+ console.log();
190
+ console.log(chalk.bold.red('━━━ STOP ━━━'));
191
+ console.log();
192
+ console.log(chalk.red('Ask the user what they want to build, then run:'));
193
+ console.log();
194
+ console.log(chalk.green(' ') + chalk.bold('codeyam editor 1 --feature "Feature Name"'));
195
+ console.log(chalk.dim(' Replace "Feature Name" with a short title for what the user described.'));
196
+ console.log(chalk.dim(' Step 1 will guide you through planning and getting user confirmation before any code is written.'));
197
+ console.log();
198
+ }
199
+ // ─── Cycle overview (no args, has project) ────────────────────────────
200
+ function printCycleOverview(root, state) {
201
+ logEvent(root, 'overview', state ? { feature: state.feature, step: state.step } : {});
202
+ console.log();
203
+ console.log(chalk.bold.cyan('━━━ Editor Mode: Feature Cycle ━━━'));
204
+ console.log();
205
+ if (state) {
206
+ console.log(chalk.yellow(`Current: Step ${state.step} (${state.label}) — "${state.feature}"`));
207
+ console.log();
208
+ console.log(chalk.green('Continue with: ') +
209
+ chalk.bold(`codeyam editor ${state.step}`));
210
+ console.log(chalk.dim('Or run ') +
211
+ chalk.bold('codeyam editor 1') +
212
+ chalk.dim(' to start a new feature'));
213
+ }
214
+ else {
215
+ console.log('Each feature follows 11 steps. You MUST run each command in order:');
216
+ console.log();
217
+ console.log(` ${chalk.bold.yellow(' 1')} ${chalk.bold('Plan')} — Plan the feature, confirm with user`);
218
+ console.log(` ${chalk.bold.yellow(' 2')} ${chalk.bold('Prototype')} — Build a working prototype fast`);
219
+ console.log(` ${chalk.bold.yellow(' 3')} ${chalk.bold('Confirm')} — Confirm prototype with user`);
220
+ console.log(` ${chalk.bold.yellow(' 4')} ${chalk.bold('Deconstruct')} — Read code, plan all extractions`);
221
+ console.log(` ${chalk.bold.yellow(' 5')} ${chalk.bold('Extract')} — TDD extraction of functions + components`);
222
+ console.log(` ${chalk.bold.yellow(' 6')} ${chalk.bold('Glossary')} — Record functions in glossary`);
223
+ console.log(` ${chalk.bold.yellow(' 7')} ${chalk.bold('Analyze')} — Analyze and verify components`);
224
+ console.log(` ${chalk.bold.yellow(' 8')} ${chalk.bold('App Scenarios')} — Create app-level scenarios`);
225
+ console.log(` ${chalk.bold.yellow(' 9')} ${chalk.bold('User Scenarios')} — Create user-persona scenarios`);
226
+ console.log(` ${chalk.bold.yellow('10')} ${chalk.bold('Verify')} — Review screenshots, check for errors`);
227
+ console.log(` ${chalk.bold.yellow('11')} ${chalk.bold('Review')} — Present summary, get approval`);
228
+ console.log();
229
+ console.log(chalk.green('Start now: ') + chalk.bold('codeyam editor 1'));
230
+ }
231
+ console.log();
232
+ }
233
+ // ─── Step 1: Plan ─────────────────────────────────────────────────────
234
+ function printStep1(root, feature) {
235
+ clearState(root);
236
+ // If feature is provided, save initial state so step 2 can pick it up
237
+ if (feature) {
238
+ const now = new Date().toISOString();
239
+ writeState(root, {
240
+ feature,
241
+ step: 1,
242
+ label: STEP_LABELS[1],
243
+ startedAt: now,
244
+ featureStartedAt: now,
245
+ });
246
+ }
247
+ logEvent(root, 'step', { step: 1, label: 'Plan', feature });
248
+ stepHeader(1, 'Plan', feature);
249
+ console.log('Plan the feature before writing ANY code.');
250
+ console.log();
251
+ console.log(chalk.bold('Checklist:'));
252
+ checkbox('Read `.codeyam/glossary.json` for reusable functions/components');
253
+ checkbox('Ask the user what they want to build (if not already described)');
254
+ checkbox('Ask clarifying questions using `AskUserQuestion` with selectable options');
255
+ console.log(chalk.dim(' Use AskUserQuestion for EVERY clarifying question — give 2-4 concrete options the user can pick from.'));
256
+ console.log(chalk.dim(' Focus on what the USER will see and do, not on databases, APIs, or components.'));
257
+ console.log(chalk.dim(' Good: "What should happen when there are no results?" → options: "Show empty state message", "Show suggestions"'));
258
+ console.log(chalk.dim(' Bad: Free-form text asking "What do you think about the data model?"'));
259
+ console.log(chalk.dim(' You can ask up to 4 questions at once. Bundle related questions into a single AskUserQuestion call.'));
260
+ checkbox("Summarize what you'll build in plain language the user can verify against their vision");
261
+ console.log();
262
+ console.log(chalk.bold('Present a selection menu to the user (use AskUserQuestion):'));
263
+ console.log(chalk.green(' "Looks good, start building!"') +
264
+ chalk.dim(' — proceed to step 2'));
265
+ console.log(chalk.yellow(' "I\'d like some changes"') +
266
+ chalk.dim(' — user describes changes, you revise the plan, then re-present'));
267
+ console.log();
268
+ console.log(chalk.dim('This step is for understanding user goals and getting buy-in. Code comes in Step 2.'));
269
+ console.log();
270
+ console.log(chalk.bold.red('━━━ STOP ━━━'));
271
+ console.log();
272
+ console.log(chalk.red('Complete each checklist item above before proceeding to the next step.'));
273
+ console.log();
274
+ console.log(chalk.yellow('Wait for user confirmation before moving on.'));
275
+ console.log();
276
+ console.log(chalk.bold.yellow('Present the following progress tracker to the user (copy it verbatim):'));
277
+ printProgressTracker(1);
278
+ console.log();
279
+ console.log(chalk.yellow('For the CURRENT step (→), show each checklist item with ✓ (done) or ✗ (skipped + reason).'));
280
+ console.log(chalk.yellow('If any items are ✗, explain why and ask if the user wants to address them.'));
281
+ console.log();
282
+ console.log(chalk.green('When done, run: ') +
283
+ chalk.bold('codeyam editor 2 --feature "Feature Name"'));
284
+ console.log(chalk.dim(' Replace "Feature Name" with a short title for what you just described.'));
285
+ console.log();
286
+ }
287
+ // ─── Step 2: Prototype ────────────────────────────────────────────────
288
+ function printStep2(root, feature) {
289
+ const port = getServerPort();
290
+ const projectExists = hasProject(root);
291
+ const now = new Date().toISOString();
292
+ writeState(root, {
293
+ feature,
294
+ step: 2,
295
+ label: STEP_LABELS[2],
296
+ startedAt: now,
297
+ featureStartedAt: now,
298
+ });
299
+ logEvent(root, 'step', { step: 2, label: 'Prototype', feature });
300
+ stepHeader(2, 'Prototype', feature);
301
+ console.log('Build fast with real data. Prioritize speed over quality.');
302
+ console.log();
303
+ // If no project exists yet, include scaffolding instructions first
304
+ if (!projectExists) {
305
+ const templateDir = path.join(__dirname, '..', '..', 'templates', 'nextjs-prisma-sqlite');
306
+ const hasTemplate = fs.existsSync(templateDir);
307
+ console.log(chalk.bold('Scaffold the project:'));
308
+ if (hasTemplate) {
309
+ checkbox('Copy the project template and install dependencies');
310
+ console.log();
311
+ console.log(chalk.dim(' Copy template (Next.js + Prisma 7 + SQLite, pre-configured):'));
312
+ console.log(chalk.dim(` cp -r ${templateDir}/* .`));
313
+ console.log(chalk.dim(` cp ${templateDir}/.env .`));
314
+ console.log(chalk.dim(` cp ${templateDir}/gitignore .gitignore`));
315
+ console.log(chalk.dim(' npm install'));
316
+ console.log();
317
+ checkbox('Define your data models in `prisma/schema.prisma`');
318
+ console.log(chalk.dim(" Replace the placeholder Todo model with your app's models"));
319
+ console.log();
320
+ checkbox('Push schema and seed the database');
321
+ console.log(chalk.dim(' npm run db:push'));
322
+ console.log(chalk.dim(' # Edit prisma/seed.ts with your seed data, then:'));
323
+ console.log(chalk.dim(' npm run db:seed'));
324
+ console.log();
325
+ console.log(chalk.dim(' See PRISMA_SETUP.md for Prisma patterns and important warnings.'));
326
+ console.log(chalk.dim(' Key: import { prisma } from "@/app/lib/prisma" in API routes.'));
327
+ console.log(chalk.dim(' Key: Seed scripts must use the adapter pattern (see prisma/seed.ts).'));
328
+ }
329
+ else {
330
+ checkbox('Scaffold the project (Next.js recommended) using temp-dir-rsync pattern');
331
+ console.log();
332
+ console.log(chalk.dim(' Scaffolding pattern (avoids .claude/ conflicts):'));
333
+ console.log(chalk.dim(' SCAFFOLD_DIR="/tmp/codeyam-scaffold-$$" && mkdir -p "$SCAFFOLD_DIR"'));
334
+ console.log(chalk.dim(' npx create-next-app@latest "$SCAFFOLD_DIR" --typescript --tailwind --eslint \\'));
335
+ console.log(chalk.dim(' --app --no-src-dir --no-import-alias --no-react-compiler --turbopack'));
336
+ console.log(chalk.dim(' rsync -a --exclude=\'.git\' "$SCAFFOLD_DIR/" . && rm -rf "$SCAFFOLD_DIR"'));
337
+ console.log();
338
+ checkbox('Set up Prisma + SQLite database');
339
+ console.log(chalk.dim(' npm install prisma @prisma/client @prisma/adapter-better-sqlite3 better-sqlite3'));
340
+ console.log(chalk.dim(' npm install -D @types/better-sqlite3'));
341
+ console.log(chalk.dim(' npx prisma init --datasource-provider sqlite'));
342
+ console.log(chalk.dim(' # Define schema, then: npx prisma db push'));
343
+ }
344
+ console.log();
345
+ checkbox('Initialize git so analysis and commits work');
346
+ console.log(chalk.dim(' git init && git add -A && git commit -m "Initial commit"'));
347
+ console.log();
348
+ checkbox('Run `codeyam init --force --keep-server` to detect the project and configure it');
349
+ console.log(chalk.dim(' This auto-detects webapps and configures the start command for analysis'));
350
+ console.log();
351
+ checkbox('Verify `.codeyam/config.json` has `startCommand` in the webapp entry');
352
+ console.log(chalk.dim(' Should look like: "startCommand": { "command": "sh", "args": ["-c", "npm run dev -- --port $PORT"] }'));
353
+ console.log(chalk.dim(' If missing, add it manually. $PORT is replaced at runtime by the analyzer.'));
354
+ console.log();
355
+ checkbox(`Notify CodeYam: \`curl -s -X POST http://localhost:${port}/api/editor-refresh\``);
356
+ console.log();
357
+ console.log(chalk.bold('Build the feature:'));
358
+ }
359
+ console.log(chalk.bold('Checklist:'));
360
+ checkbox('Create/update API routes (real database reads via Prisma)');
361
+ checkbox('Seed the database with demo data');
362
+ checkbox('Build the page/feature UI components');
363
+ checkbox('Verify the dev server shows the changes');
364
+ console.log();
365
+ console.log(chalk.bold('Verify the dev server:'));
366
+ console.log(chalk.dim(` # Get dev server URL: curl -s http://localhost:${port}/api/editor-dev-server`));
367
+ console.log(chalk.dim(' # Check page loads: curl -s -o /dev/null -w "%{http_code}" http://localhost:<dev-port>'));
368
+ console.log(chalk.dim(' # Check API routes: curl -s http://localhost:<dev-port>/api/your-route'));
369
+ console.log();
370
+ console.log(chalk.bold('Verify before proceeding:'));
371
+ console.log(chalk.yellow(' Verify everything works before presenting the prototype to the user.'));
372
+ checkbox('Verify the page loads: curl the dev server URL and confirm HTTP 200 (not an error page)');
373
+ checkbox('Verify API routes return valid JSON: curl each route and confirm no error responses');
374
+ checkbox('Check for broken images: look at any <img> src attributes and verify the assets exist');
375
+ checkbox('Check the dev server terminal output for runtime errors (missing modules, failed imports)');
376
+ console.log(chalk.dim(' If any check fails, fix the issue and re-verify before proceeding.'));
377
+ console.log();
378
+ console.log(chalk.dim('Focus on building the prototype. Scenarios and refactoring happen in later steps.'));
379
+ stopGate(2);
380
+ }
381
+ // ─── Step 3: Confirm ──────────────────────────────────────────────────
382
+ function printStep3(root, feature) {
383
+ const port = getServerPort();
384
+ const prevState = readState(root);
385
+ writeState(root, {
386
+ feature,
387
+ step: 3,
388
+ label: STEP_LABELS[3],
389
+ startedAt: new Date().toISOString(),
390
+ featureStartedAt: prevState?.featureStartedAt || new Date().toISOString(),
391
+ });
392
+ logEvent(root, 'step', { step: 3, label: 'Confirm', feature });
393
+ stepHeader(3, 'Confirm', feature);
394
+ console.log('Summarize what was built and get user confirmation.');
395
+ console.log();
396
+ console.log(chalk.bold('Before presenting — verify everything works:'));
397
+ checkbox(`Refresh the preview: \`curl -s -X POST http://localhost:${port}/api/editor-refresh\``);
398
+ checkbox('Verify the page loads without errors (no error pages, no blank screens)');
399
+ checkbox('Verify all images and assets render correctly (no broken images)');
400
+ checkbox('Verify API routes return valid data (curl each route)');
401
+ console.log(chalk.yellow(' Do not present to the user until all checks pass. Fix issues first.'));
402
+ console.log();
403
+ console.log(chalk.bold('Then present to the user:'));
404
+ checkbox('Summarize what was built (routes, components, data)');
405
+ checkbox('Show the user the current state of the prototype');
406
+ console.log();
407
+ console.log(chalk.bold('Present a selection menu to the user (use AskUserQuestion):'));
408
+ console.log(chalk.green(' "Yes, this looks right!"') +
409
+ chalk.dim(' — proceed to step 4'));
410
+ console.log(chalk.yellow(' "I\'d like some changes"') +
411
+ chalk.dim(' — user describes changes, you make them, then re-present'));
412
+ console.log();
413
+ console.log(chalk.dim('Wait for user approval before moving on. Refactoring and scenarios happen in later steps.'));
414
+ stopGate(3, { confirm: true });
415
+ }
416
+ // ─── Step 4: Deconstruct ──────────────────────────────────────────────
417
+ function printStep4(root, feature) {
418
+ const prevState = readState(root);
419
+ writeState(root, {
420
+ feature,
421
+ step: 4,
422
+ label: STEP_LABELS[4],
423
+ startedAt: new Date().toISOString(),
424
+ featureStartedAt: prevState?.featureStartedAt || new Date().toISOString(),
425
+ });
426
+ logEvent(root, 'step', { step: 4, label: 'Deconstruct', feature });
427
+ stepHeader(4, 'Deconstruct', feature);
428
+ console.log(chalk.bold('Goal: pages contain ONLY components. Components contain ONLY sub-components.'));
429
+ console.log(chalk.yellow('This step is read and plan only. Code extraction happens in step 5.'));
430
+ console.log();
431
+ console.log(chalk.bold.red('THE RULE: No direct JSX in page files.'));
432
+ console.log(chalk.yellow(' After extraction, a page/route file should import and compose components — nothing else.'));
433
+ console.log(chalk.yellow(' Every distinct visual section in the page is its own component.'));
434
+ console.log(chalk.yellow(' Every component that renders multiple distinct sections should be split into sub-components.'));
435
+ console.log(chalk.yellow(' If a component has N visually distinct parts, it should compose N sub-components.'));
436
+ console.log();
437
+ console.log(chalk.bold('Checklist:'));
438
+ checkbox('Read `.codeyam/glossary.json` — note reusable functions/components');
439
+ checkbox('Read EVERY file created or modified in this session');
440
+ console.log(chalk.yellow(' For EACH file, identify EVERY extractable piece:'));
441
+ console.log(chalk.yellow(' Components: headers, nav, loading states, empty states, error states,'));
442
+ console.log(chalk.yellow(' badges/pills, image containers, card sections, form fields, modals,'));
443
+ console.log(chalk.yellow(' titles, descriptions, rating displays, status indicators, buttons'));
444
+ console.log(chalk.yellow(' Functions: data transforms, calculations, formatting, validation,'));
445
+ console.log(chalk.yellow(' API response shaping, any logic that is not directly about rendering'));
446
+ console.log(chalk.yellow(' Hooks: data fetching, state management, side effects'));
447
+ console.log();
448
+ checkbox('Write a numbered extraction plan listing EVERYTHING you will extract');
449
+ console.log(chalk.yellow(' The end state: every page file is ONLY imports + component composition.'));
450
+ console.log(chalk.yellow(' No raw <div>, <span>, <h1>, <p>, <img>, or <ul> in page files.'));
451
+ console.log(chalk.yellow(' Every visual section in every component is itself a component.'));
452
+ console.log();
453
+ console.log(chalk.yellow(' For each item in the plan, note:'));
454
+ console.log(chalk.yellow(' — What it is (component, function, hook)'));
455
+ console.log(chalk.yellow(' — Where it currently lives (source file + approximate lines)'));
456
+ console.log(chalk.yellow(' — Where it will go (new file path)'));
457
+ console.log();
458
+ console.log(chalk.dim('Present the numbered plan, then proceed to step 5 to execute it.'));
459
+ stopGate(4);
460
+ }
461
+ // ─── Step 5: Extract ──────────────────────────────────────────────────
462
+ function printStep5(root, feature) {
463
+ const prevState = readState(root);
464
+ writeState(root, {
465
+ feature,
466
+ step: 5,
467
+ label: STEP_LABELS[5],
468
+ startedAt: new Date().toISOString(),
469
+ featureStartedAt: prevState?.featureStartedAt || new Date().toISOString(),
470
+ });
471
+ logEvent(root, 'step', { step: 5, label: 'Extract', feature });
472
+ stepHeader(5, 'Extract', feature);
473
+ console.log('Execute your extraction plan from step 4.');
474
+ console.log();
475
+ console.log(chalk.bold('Components:'));
476
+ checkbox('Extract each component from your plan into its own file');
477
+ checkbox('Page/route files must contain ZERO direct JSX — only imported components');
478
+ checkbox('Every component that renders multiple sections must be split into sub-components');
479
+ console.log(chalk.dim(' No tests needed — visual verification happens in step 7'));
480
+ console.log();
481
+ console.log(chalk.bold('Library functions (TDD):'));
482
+ checkbox('For each function: write MULTIPLE failing tests FIRST, then extract to make them pass');
483
+ console.log(chalk.dim(' Cover: typical inputs, edge cases, empty/null inputs, error conditions'));
484
+ console.log(chalk.dim(' Aim for 3-8 test cases per function depending on complexity'));
485
+ checkbox('Place test files next to source: `app/lib/drinks.ts` → `app/lib/drinks.test.ts`');
486
+ console.log(chalk.yellow(' Tests ARE the only coverage for library functions — step 7 only captures component screenshots.'));
487
+ console.log();
488
+ console.log(chalk.bold('Recursive pass:'));
489
+ checkbox('Re-read EVERY new file you just created — extract components from components, functions from functions');
490
+ checkbox('Keep going until every file is a thin shell: just imports and composition');
491
+ console.log(chalk.yellow(' Check: does any file contain raw <div>, <span>, <h1>, <p>, <img>, or <ul>?'));
492
+ console.log(chalk.yellow(' If yes → that JSX section is a component waiting to be extracted.'));
493
+ console.log();
494
+ console.log(chalk.bold('Verify before proceeding:'));
495
+ checkbox('Run all tests and verify they pass');
496
+ checkbox('Page files contain ONLY imports + component composition — no raw HTML tags');
497
+ checkbox('Every component renders ONE thing or composes sub-components — no multi-section JSX');
498
+ console.log(chalk.dim('Reuse glossary functions when they fit naturally. Extract a new function when the use case diverges.'));
499
+ console.log();
500
+ console.log(chalk.dim('Focus on TDD for functions and extraction for components. Scenarios come in later steps.'));
501
+ stopGate(5);
502
+ }
503
+ // ─── Step 6: Glossary ─────────────────────────────────────────────────
504
+ function printStep6(root, feature) {
505
+ const prevState = readState(root);
506
+ writeState(root, {
507
+ feature,
508
+ step: 6,
509
+ label: STEP_LABELS[6],
510
+ startedAt: new Date().toISOString(),
511
+ featureStartedAt: prevState?.featureStartedAt || new Date().toISOString(),
512
+ });
513
+ logEvent(root, 'step', { step: 6, label: 'Glossary', feature });
514
+ stepHeader(6, 'Glossary', feature);
515
+ console.log('Record all new functions/components in `.codeyam/glossary.json`.');
516
+ console.log();
517
+ console.log(chalk.bold('Checklist:'));
518
+ checkbox("Read `.codeyam/glossary.json` (create if it doesn't exist)");
519
+ checkbox('Add an entry for each new function/component extracted in step 5');
520
+ checkbox('Each entry should have: name, filePath, description, parameters, returnType, tags, feature');
521
+ checkbox('For each function with a test file from step 5, set `testFile` to the relative path');
522
+ console.log();
523
+ console.log(chalk.bold('Entry format:'));
524
+ console.log(chalk.dim(' { "name": "calculateTotal", "filePath": "app/utils/pricing.ts",'));
525
+ console.log(chalk.dim(' "description": "Calculates total price including tax and discounts",'));
526
+ console.log(chalk.dim(' "parameters": [{ "name": "items", "type": "CartItem[]" }],'));
527
+ console.log(chalk.dim(' "returnType": "number", "tags": ["pricing"],'));
528
+ console.log(chalk.dim(' "testFile": "app/utils/pricing.test.ts",'));
529
+ console.log(chalk.dim(` "feature": "${feature}", "createdAt": "..." }`));
530
+ console.log();
531
+ console.log(chalk.dim('Focus on updating the glossary. Application code and scenarios come in later steps.'));
532
+ stopGate(6);
533
+ }
534
+ // ─── Step 7: Analyze ──────────────────────────────────────────────────
535
+ function printStep7(root, feature) {
536
+ const port = getServerPort();
537
+ const prevState = readState(root);
538
+ writeState(root, {
539
+ feature,
540
+ step: 7,
541
+ label: STEP_LABELS[7],
542
+ startedAt: new Date().toISOString(),
543
+ featureStartedAt: prevState?.featureStartedAt || new Date().toISOString(),
544
+ });
545
+ logEvent(root, 'step', { step: 7, label: 'Analyze', feature });
546
+ stepHeader(7, 'Analyze and Verify', feature);
547
+ console.log('Verify visual components (via isolation routes) and library functions (via tests).');
548
+ console.log();
549
+ console.log(chalk.bold('Visual Components — Component Isolation:'));
550
+ checkbox('List all files with new/modified visual components from step 5');
551
+ checkbox('Ensure `.gitignore` includes `**/codeyam-isolate*` (add if missing)');
552
+ checkbox('For each visual component:');
553
+ console.log(chalk.dim(' 1. Read the source AND find where it is used in the app to understand:'));
554
+ console.log(chalk.dim(' — Props/interface'));
555
+ console.log(chalk.dim(' — Container width in the real app (e.g. card in a 3-col grid → max-w-sm)'));
556
+ console.log(chalk.dim(' 2. Plan multiple scenarios that exercise the component like tests:'));
557
+ console.log(chalk.dim(' — Default/happy path with typical data'));
558
+ console.log(chalk.dim(' — Edge cases: empty/missing data, long text, maximum items, zero counts'));
559
+ console.log(chalk.dim(' — Different visual states: loading, error, disabled, selected, hover'));
560
+ console.log(chalk.dim(' — Boundary values: single item vs many, min/max ratings, very long names'));
561
+ console.log(chalk.dim(' 3. Create ONE isolation route per component with a scenarios map and ?s= query param:'));
562
+ console.log(chalk.dim(' Remix: app/routes/codeyam-isolate.ComponentName.tsx → /codeyam-isolate/ComponentName'));
563
+ console.log(chalk.dim(' Next.js: app/codeyam-isolate/ComponentName/page.tsx → /codeyam-isolate/ComponentName'));
564
+ console.log(chalk.dim(' The route defines a `scenarios` object mapping scenario names to props,'));
565
+ console.log(chalk.dim(' reads `?s=ScenarioName` from the URL, and renders the component with those props.'));
566
+ console.log(chalk.dim(' Wrap the component in a capture container with id="codeyam-capture":'));
567
+ console.log(chalk.dim(' <div id="codeyam-capture" style={{ display:"inline-block", padding:"20px" }}>'));
568
+ console.log(chalk.dim(' <div style={{ width:"100%", maxWidth:"..." }}> ← match the app\'s container width'));
569
+ console.log(chalk.dim(' e.g. card in a 3-col grid → maxWidth:"24rem", full-width component → omit maxWidth'));
570
+ console.log(chalk.dim(' The screenshot captures just this wrapper, so the component fills the image.'));
571
+ console.log(chalk.dim(' Center the wrapper on the page (flexbox center both axes) and set a page background'));
572
+ console.log(chalk.dim(' color that matches where the component normally appears (e.g. white for light UIs).'));
573
+ console.log(chalk.dim(' 4. Wait 2 seconds for HMR, then register + capture each scenario:'));
574
+ console.log(chalk.dim(` codeyam editor register '{"name":"ComponentName - Scenario",`));
575
+ console.log(chalk.dim(` "componentName":"ComponentName","componentPath":"path/to/file.tsx",`));
576
+ console.log(chalk.dim(` "url":"/codeyam-isolate/ComponentName?s=Scenario",`));
577
+ console.log(chalk.dim(` "mockData":{"routes":{"/api/...":{"body":[...]}}}}'`));
578
+ console.log(chalk.dim(' url is a PATH (starts with /) — the proxy routes it and intercepts API calls'));
579
+ console.log(chalk.dim(' mockData.routes provides data for API calls the component makes internally'));
580
+ console.log(chalk.dim(' (omit mockData if the component has no internal API calls)'));
581
+ console.log(chalk.yellow(' 5. IMPORTANT: Check the register response for `clientErrors` array'));
582
+ console.log(chalk.yellow(' If clientErrors is non-empty → fix the isolation route and re-register'));
583
+ console.log(chalk.yellow(' Fix client errors and re-register before moving on'));
584
+ console.log(chalk.dim(' Isolation routes stay in the project (in .gitignore) so the editor preview can display them'));
585
+ console.log();
586
+ console.log(chalk.bold('Library Functions — run tests:'));
587
+ checkbox('Run ALL test files created in step 5');
588
+ console.log(chalk.dim(' Example: npx vitest run app/lib/drinks.test.ts'));
589
+ checkbox('Verify every test passes');
590
+ checkbox('If any test fails, fix the source code and re-run');
591
+ console.log();
592
+ console.log(chalk.dim('Do not proceed until both component isolations and library tests pass.'));
593
+ stopGate(7);
594
+ }
595
+ // ─── Step 8: App Scenarios ────────────────────────────────────────────
596
+ function printStep8(root, feature) {
597
+ const port = getServerPort();
598
+ const prevState = readState(root);
599
+ writeState(root, {
600
+ feature,
601
+ step: 8,
602
+ label: STEP_LABELS[8],
603
+ startedAt: new Date().toISOString(),
604
+ featureStartedAt: prevState?.featureStartedAt || new Date().toISOString(),
605
+ });
606
+ logEvent(root, 'step', { step: 8, label: 'App Scenarios', feature });
607
+ stepHeader(8, 'App Scenarios', feature);
608
+ console.log('Create app-level scenarios representing different data states.');
609
+ console.log();
610
+ console.log(chalk.bold('Checklist:'));
611
+ checkbox('Create scenarios for key data states (empty, loaded, error)');
612
+ console.log(chalk.dim(' Each scenario provides data across ALL API routes for that state'));
613
+ console.log(chalk.dim(' Name app scenarios with "App - " prefix: "App - Empty", "App - Full Catalog", "App - API Error"'));
614
+ checkbox('Register each scenario (auto-captures screenshot):');
615
+ console.log(chalk.dim(` codeyam editor register '{"name":"App - Empty","description":"...","mockData":{"routes":{"/api/...":{"body":[...]}}}}'`));
616
+ checkbox('After each registration, check the response for `clientErrors`');
617
+ console.log(chalk.yellow(' If clientErrors is non-empty → fix the issue and re-register the scenario'));
618
+ console.log(chalk.yellow(' Fix client errors and re-register before moving on'));
619
+ console.log();
620
+ console.log(chalk.dim('Focus on creating and registering app-level scenarios. Code fixes happen in step 10 if needed.'));
621
+ stopGate(8);
622
+ }
623
+ // ─── Step 9: User Scenarios ───────────────────────────────────────────
624
+ function printStep9(root, feature) {
625
+ const port = getServerPort();
626
+ const prevState = readState(root);
627
+ writeState(root, {
628
+ feature,
629
+ step: 9,
630
+ label: STEP_LABELS[9],
631
+ startedAt: new Date().toISOString(),
632
+ featureStartedAt: prevState?.featureStartedAt || new Date().toISOString(),
633
+ });
634
+ logEvent(root, 'step', { step: 9, label: 'User Scenarios', feature });
635
+ stepHeader(9, 'User Scenarios', feature);
636
+ console.log('Create per-persona scenarios if the app has users. Skip to step 10 if no users.');
637
+ console.log();
638
+ console.log(chalk.bold('If the app has users:'));
639
+ checkbox('Create scenarios for each user persona (admin, regular user, new user)');
640
+ console.log(chalk.dim(' Each persona scenario provides data across ALL API routes for that user type'));
641
+ checkbox('Register each persona scenario (auto-captures screenshot):');
642
+ console.log(chalk.dim(` codeyam editor register '{"name":"...","description":"...","mockData":{"routes":{"/api/...":{"body":[...]}}}}'`));
643
+ checkbox('After each registration, check the response for `clientErrors`');
644
+ console.log(chalk.yellow(' If clientErrors is non-empty → fix the issue and re-register the scenario'));
645
+ console.log(chalk.yellow(' Fix client errors and re-register before moving on'));
646
+ console.log();
647
+ console.log(chalk.bold('If the app has NO users:'));
648
+ console.log(chalk.dim(' Skip this step and proceed to step 10 (Verify).'));
649
+ console.log();
650
+ console.log(chalk.dim('Focus on creating user-persona scenarios (or skip if no users). Code fixes happen in step 10 if needed.'));
651
+ stopGate(9);
652
+ }
653
+ // ─── Step 10: Verify ──────────────────────────────────────────────────
654
+ function printStep10(root, feature) {
655
+ const port = getServerPort();
656
+ const prevState = readState(root);
657
+ writeState(root, {
658
+ feature,
659
+ step: 10,
660
+ label: STEP_LABELS[10],
661
+ startedAt: new Date().toISOString(),
662
+ featureStartedAt: prevState?.featureStartedAt || new Date().toISOString(),
663
+ });
664
+ logEvent(root, 'step', { step: 10, label: 'Verify', feature });
665
+ stepHeader(10, 'Verify', feature);
666
+ console.log('Verify component isolation screenshots, editor scenarios, and library tests.');
667
+ console.log();
668
+ console.log(chalk.bold('Component isolation screenshots — verify:'));
669
+ checkbox('Review component screenshots in the App tab (grouped under Components)');
670
+ checkbox('If any screenshot looks wrong, fix the component code');
671
+ console.log(chalk.yellow(' After fixing a visual component, re-register the affected scenarios:'));
672
+ console.log(chalk.dim(` codeyam editor register '{"name":"ComponentName - Scenario",...}'`));
673
+ console.log();
674
+ console.log(chalk.bold('Editor scenarios (App tab) — visual + error check:'));
675
+ checkbox(`Refresh the preview: \`curl -s -X POST http://localhost:${port}/api/editor-refresh\``);
676
+ checkbox('Click through each app-level and user-persona scenario in the preview');
677
+ checkbox(`Check for client-side errors: \`curl -s http://localhost:${port}/api/editor-client-errors\``);
678
+ console.log(chalk.yellow(' If `hasErrors` is true: list each scenario with errors, fix the source code,'));
679
+ console.log(chalk.yellow(' re-register the affected scenarios, and re-check until hasErrors is false'));
680
+ console.log(chalk.dim(' Common errors: React errors, failed fetches, undefined references, hydration mismatches'));
681
+ checkbox('Verify no broken images in any scenario screenshots');
682
+ console.log();
683
+ console.log(chalk.bold('Library functions — test check:'));
684
+ checkbox('Re-run all test files from step 5 to confirm they still pass');
685
+ console.log(chalk.dim(' Example: npx vitest run app/lib/drinks.test.ts'));
686
+ checkbox('If any test fails, fix the source code and re-run');
687
+ console.log();
688
+ console.log(chalk.dim('Focus on fixing issues. All component screenshots, scenarios, and tests must be clean before proceeding.'));
689
+ stopGate(10);
690
+ }
691
+ // ─── Step 11: Review ──────────────────────────────────────────────────
692
+ function printStep11(root, feature) {
693
+ const port = getServerPort();
694
+ const prevState = readState(root);
695
+ writeState(root, {
696
+ feature,
697
+ step: 11,
698
+ label: STEP_LABELS[11],
699
+ startedAt: new Date().toISOString(),
700
+ featureStartedAt: prevState?.featureStartedAt || new Date().toISOString(),
701
+ });
702
+ logEvent(root, 'step', { step: 11, label: 'Review', feature });
703
+ stepHeader(11, 'Review', feature);
704
+ console.log('Present a full summary, verify screenshots, then let the user save or revise.');
705
+ console.log();
706
+ console.log(chalk.bold('Phase 1 — Summary:'));
707
+ checkbox('Summarize the feature that was built');
708
+ checkbox('List all components and functions created');
709
+ checkbox('List glossary entries added in step 6');
710
+ checkbox('List all scenarios (app-level and user-persona)');
711
+ checkbox('Report analysis status (completed/in-progress from step 7)');
712
+ checkbox('Report verification status from step 10 (all clean?)');
713
+ checkbox(`Refresh the preview: \`curl -s -X POST http://localhost:${port}/api/dev-mode-refresh\``);
714
+ checkbox(`Get scenario list: \`curl -s http://localhost:${port}/api/editor-scenarios\``);
715
+ checkbox('Present scenarios in a markdown table — one scenario per row');
716
+ console.log(chalk.yellow(' EVERY scenario must use {{scenario:Name:ID}} — the terminal makes these clickable.'));
717
+ console.log(chalk.yellow(' Strip the component prefix: "DrinkCard - Default" → just "Default".'));
718
+ console.log(chalk.yellow(' Component name on first row of each group, blank for subsequent rows.'));
719
+ console.log();
720
+ console.log(chalk.dim(' Example:'));
721
+ console.log(chalk.dim(' | Component | Scenario |'));
722
+ console.log(chalk.dim(' |---|---|'));
723
+ console.log(chalk.dim(' | **App** | {{scenario:Full Catalog:abc}} |'));
724
+ console.log(chalk.dim(' | | {{scenario:Empty:def}} |'));
725
+ console.log(chalk.dim(' | | {{scenario:Error:ghi}} |'));
726
+ console.log(chalk.dim(' | **StarRating** | {{scenario:Perfect:jkl}} |'));
727
+ console.log(chalk.dim(' | | {{scenario:Medium:mno}} |'));
728
+ console.log();
729
+ console.log(chalk.bold('Phase 2 — Screenshot & error verification:'));
730
+ console.log(chalk.yellow(' CRITICAL: Verify screenshots AND check for client-side errors.'));
731
+ console.log();
732
+ console.log(chalk.bold(' Component isolation screenshots:'));
733
+ checkbox('Verify each component has screenshots in the App tab (grouped under Components)');
734
+ checkbox('If any are missing, re-register them using `codeyam editor register`');
735
+ console.log();
736
+ console.log(chalk.bold(' Client-side errors:'));
737
+ checkbox(`Check for errors: \`curl -s http://localhost:${port}/api/editor-client-errors\``);
738
+ checkbox('If `hasErrors` is true, list the errors and fix them in the source code');
739
+ checkbox('After fixing, re-capture affected scenarios to clear the errors');
740
+ console.log();
741
+ checkbox('Do not proceed until all components have screenshots and client errors are resolved');
742
+ console.log();
743
+ checkbox('Switch the active scenario to the best demo state for the feature');
744
+ console.log(chalk.dim(` curl -s -X POST http://localhost:${port}/api/editor-switch-scenario \\`));
745
+ console.log(chalk.dim(` -H 'Content-Type: application/json' -d '{"scenarioSlug":"...","scenarioId":"..."}'`));
746
+ console.log(chalk.dim(' Pick the scenario that best showcases the feature (not an error/empty state)'));
747
+ checkbox('Present the summary (with screenshot and error status) to the user');
748
+ console.log();
749
+ console.log(chalk.bold('Phase 3 — Journal entry (create or update):'));
750
+ checkbox('Write a concise description of what was built (2-3 sentences)');
751
+ checkbox(`First time at step 11 — create journal entry with ALL session screenshots:`);
752
+ console.log(chalk.dim(` curl -s -X POST http://localhost:${port}/api/editor-journal-entry \\`));
753
+ console.log(chalk.dim(` -H 'Content-Type: application/json' \\`));
754
+ console.log(chalk.dim(` -d '{"title":"...","type":"feature","description":"...","includeSessionScenarios":true}'`));
755
+ console.log(chalk.dim(' includeSessionScenarios auto-discovers component + app + user persona screenshots'));
756
+ checkbox(`Returning after changes — update the existing journal entry:`);
757
+ console.log(chalk.dim(` curl -s -X PATCH http://localhost:${port}/api/editor-journal-update \\`));
758
+ console.log(chalk.dim(` -H 'Content-Type: application/json' \\`));
759
+ console.log(chalk.dim(` -d '{"time":"<journal entry time>","description":"<updated description>"}'`));
760
+ console.log();
761
+ console.log(chalk.bold('Phase 4 — Present a selection menu to the user (use AskUserQuestion):'));
762
+ console.log(chalk.green(' "Save & commit"') +
763
+ chalk.dim(' — git commit all changes and record in journal'));
764
+ console.log(chalk.yellow(' "I\'d like to make some changes"') +
765
+ chalk.dim(' — describe changes, then re-verify'));
766
+ console.log();
767
+ console.log(chalk.bold('If the user chooses "Save & commit":'));
768
+ checkbox(`Git commit using the journal description: \`curl -s -X POST http://localhost:${port}/api/editor-commit -H 'Content-Type: application/json' -d '{"message":"feat: <title>\\n\\n<journal description>"}'\``);
769
+ console.log(chalk.dim(' The commit message body MUST match the journal description exactly'));
770
+ checkbox(`Update journal with commit SHA: \`curl -s -X PATCH http://localhost:${port}/api/editor-journal-update -H 'Content-Type: application/json' -d '{"time":"<journal entry time>","commitSha":"<sha>","commitMessage":"feat: <title>"}'\``);
771
+ console.log(chalk.green(' Then run: ') +
772
+ chalk.bold('codeyam editor 1') +
773
+ chalk.green(' to start the next feature'));
774
+ console.log();
775
+ console.log(chalk.bold('If the user chooses "Make changes":'));
776
+ checkbox('Ask what changes the user wants');
777
+ checkbox('Make the requested changes');
778
+ console.log(chalk.yellow(' Then run: ') +
779
+ chalk.bold('codeyam editor 10') +
780
+ chalk.yellow(' to re-verify, which flows back to step 11'));
781
+ console.log();
782
+ console.log(chalk.dim('Complete all phases in order: summary, screenshot verification, journal entry, user menu.'));
783
+ stopGate(11, { confirm: true });
784
+ }
785
+ // ─── Command definition ───────────────────────────────────────────────
786
+ // ─── Analyze-imports subcommand ────────────────────────────────────────
787
+ /**
788
+ * `codeyam editor analyze-imports`
789
+ *
790
+ * Runs data-structure-only analysis for all glossary entities, then outputs
791
+ * an import graph and entity data structures as JSON to stdout.
792
+ */
793
+ async function handleAnalyzeImports() {
794
+ const root = getProjectRoot();
795
+ // Read glossary
796
+ const glossaryPath = path.join(root, '.codeyam', 'glossary.json');
797
+ if (!fs.existsSync(glossaryPath)) {
798
+ console.error(chalk.red('Error: .codeyam/glossary.json not found.'));
799
+ console.error(chalk.dim(' Run codeyam editor 6 to create the glossary first.'));
800
+ process.exit(1);
801
+ }
802
+ let glossaryEntries;
803
+ try {
804
+ glossaryEntries = JSON.parse(fs.readFileSync(glossaryPath, 'utf8'));
805
+ }
806
+ catch {
807
+ console.error(chalk.red('Error: Could not parse .codeyam/glossary.json.'));
808
+ process.exit(1);
809
+ }
810
+ if (!Array.isArray(glossaryEntries) || glossaryEntries.length === 0) {
811
+ console.error(chalk.red('Error: glossary.json is empty.'));
812
+ process.exit(1);
813
+ }
814
+ const filePaths = glossaryEntries.map((e) => e.filePath);
815
+ const entityNames = glossaryEntries.map((e) => e.name);
816
+ const progress = new ProgressReporter();
817
+ // Run data-structure-only analysis for all entities
818
+ progress.start('Running import analysis for all glossary entities...');
819
+ try {
820
+ await runAnalysisForEntities({
821
+ projectRoot: root,
822
+ filePaths,
823
+ entityNames,
824
+ progress,
825
+ onlyDataStructure: true,
826
+ });
827
+ }
828
+ catch (err) {
829
+ progress.fail('Analysis failed');
830
+ const msg = err instanceof Error ? err.message : String(err);
831
+ console.error(chalk.red(`Error: ${msg}`));
832
+ process.exit(1);
833
+ }
834
+ progress.succeed('Analysis complete');
835
+ // Load entities WITH metadata from database
836
+ progress.start('Loading entity metadata...');
837
+ await initializeEnvironment();
838
+ const entities = await loadEntities({});
839
+ if (!entities || entities.length === 0) {
840
+ progress.fail('No entities found in database');
841
+ process.exit(1);
842
+ }
843
+ // Deduplicate to latest versions
844
+ const latestByKey = new Map();
845
+ for (const entity of entities) {
846
+ const key = `${entity.name}::${entity.filePath}`;
847
+ const existing = latestByKey.get(key);
848
+ if (!existing ||
849
+ (entity.createdAt &&
850
+ existing.createdAt &&
851
+ entity.createdAt > existing.createdAt)) {
852
+ latestByKey.set(key, entity);
853
+ }
854
+ }
855
+ const entityNameSet = new Set(entityNames);
856
+ const latestEntities = [...latestByKey.values()].filter((e) => entityNameSet.has(e.name));
857
+ // Build import graph from importedExports metadata
858
+ const imports = {};
859
+ const entityData = {};
860
+ // Also load analyses for data structures
861
+ const entityShas = latestEntities.map((e) => e.sha);
862
+ const analyses = await loadAnalyses({ entityShas });
863
+ const analysisMap = new Map();
864
+ if (analyses) {
865
+ for (const a of analyses) {
866
+ if (!analysisMap.has(a.entitySha) ||
867
+ (a.createdAt &&
868
+ (!analysisMap.get(a.entitySha).createdAt ||
869
+ a.createdAt > analysisMap.get(a.entitySha).createdAt))) {
870
+ analysisMap.set(a.entitySha, a);
871
+ }
872
+ }
873
+ }
874
+ for (const entity of latestEntities) {
875
+ const importedExports = entity.metadata?.importedExports || [];
876
+ const importedNames = importedExports
877
+ .map((ie) => ie.name)
878
+ .filter((name) => entityNameSet.has(name));
879
+ if (importedNames.length > 0) {
880
+ imports[entity.name] = importedNames;
881
+ }
882
+ // Collect entity data with analysis data structures
883
+ const analysis = analysisMap.get(entity.sha);
884
+ const analysisMetadata = analysis?.metadata;
885
+ entityData[entity.name] = {
886
+ filePath: entity.filePath || '',
887
+ entityType: entity.entityType || 'visual',
888
+ dataForMocks: analysisMetadata?.scenariosDataStructure?.dataForMocks,
889
+ dependencySchemas: analysisMetadata?.mergedDataStructure?.dependencySchemas,
890
+ };
891
+ }
892
+ progress.succeed('Done');
893
+ // Output combined JSON
894
+ const output = { imports, entities: entityData };
895
+ console.log(JSON.stringify(output, null, 2));
896
+ }
897
+ // ─── Register subcommand ──────────────────────────────────────────────
898
+ /**
899
+ * `codeyam editor register '{"name":"...","componentName":"...",...}'`
900
+ *
901
+ * Thin CLI wrapper around POST /api/editor-register-scenario.
902
+ * Auto-approved via `Bash(codeyam:*)` — no manual approval needed.
903
+ */
904
+ async function handleRegister(jsonArg) {
905
+ if (!jsonArg) {
906
+ console.error(chalk.red('Error: JSON argument required.'));
907
+ console.error(chalk.dim(' Usage: codeyam editor register \'{"name":"DrinkCard - Default","componentName":"DrinkCard","url":"/codeyam-isolate/DrinkCard?s=Default"}\''));
908
+ process.exit(1);
909
+ }
910
+ let body;
911
+ try {
912
+ body = JSON.parse(jsonArg);
913
+ }
914
+ catch {
915
+ console.error(chalk.red('Error: Invalid JSON.'));
916
+ console.error(chalk.dim(` Received: ${jsonArg.slice(0, 200)}`));
917
+ process.exit(1);
918
+ }
919
+ const port = getServerPort();
920
+ const url = `http://localhost:${port}/api/editor-register-scenario`;
921
+ try {
922
+ const res = await fetch(url, {
923
+ method: 'POST',
924
+ headers: { 'Content-Type': 'application/json' },
925
+ body: JSON.stringify(body),
926
+ });
927
+ const data = await res.json();
928
+ console.log(JSON.stringify(data, null, 2));
929
+ if (!res.ok) {
930
+ process.exit(1);
931
+ }
932
+ }
933
+ catch (error) {
934
+ const msg = error instanceof Error ? error.message : String(error);
935
+ console.error(chalk.red(`Error: Could not reach editor server at ${url}`));
936
+ console.error(chalk.dim(` ${msg}`));
937
+ console.error(chalk.dim(' Is the editor running? Start it with: codeyam editor'));
938
+ process.exit(1);
939
+ }
940
+ }
941
+ // ─── Command definition ───────────────────────────────────────────────
942
+ const editorCommand = {
943
+ command: 'editor [step] [json]',
944
+ describe: 'Editor mode guided workflow',
945
+ builder: (yargs) => {
946
+ return yargs
947
+ .positional('step', {
948
+ type: 'string',
949
+ describe: 'Step number (1-11) or subcommand (register, analyze-imports)',
950
+ })
951
+ .positional('json', {
952
+ type: 'string',
953
+ describe: 'JSON argument for register subcommand',
954
+ })
955
+ .option('feature', {
956
+ type: 'string',
957
+ describe: 'Feature name (required for step 2)',
958
+ });
959
+ },
960
+ handler: async (argv) => {
961
+ const root = getProjectRoot();
962
+ // Subcommand: codeyam editor register '{"name":"..."}'
963
+ if (argv.step === 'register') {
964
+ await handleRegister(argv.json || '');
965
+ return;
966
+ }
967
+ // Subcommand: codeyam editor analyze-imports
968
+ if (argv.step === 'analyze-imports') {
969
+ await handleAnalyzeImports();
970
+ return;
971
+ }
972
+ const step = argv.step ? parseInt(argv.step, 10) : undefined;
973
+ if (step != null && (isNaN(step) || step < 1 || step > 11)) {
974
+ console.error(chalk.red(`Error: Invalid step "${argv.step}". Must be 1-11.`));
975
+ process.exit(1);
976
+ }
977
+ if (step == null) {
978
+ // No step specified: setup or overview
979
+ if (!hasProject(root)) {
980
+ printSetup(root);
981
+ }
982
+ else {
983
+ const state = readState(root);
984
+ printCycleOverview(root, state);
985
+ }
986
+ return;
987
+ }
988
+ const state = readState(root);
989
+ switch (step) {
990
+ case 1: {
991
+ const feature = argv.feature || undefined;
992
+ printStep1(root, feature);
993
+ break;
994
+ }
995
+ case 2: {
996
+ const feature = argv.feature || state?.feature;
997
+ if (!feature) {
998
+ console.error(chalk.red('Error: --feature "Feature Name" is required for step 2.'));
999
+ console.error(chalk.dim(' Usage: codeyam editor 2 --feature "Drink Rating System"'));
1000
+ process.exit(1);
1001
+ }
1002
+ printStep2(root, feature);
1003
+ break;
1004
+ }
1005
+ case 3:
1006
+ case 4:
1007
+ case 5:
1008
+ case 6:
1009
+ case 7:
1010
+ case 8:
1011
+ case 9:
1012
+ case 10:
1013
+ case 11: {
1014
+ const feature = argv.feature || state?.feature;
1015
+ if (!feature) {
1016
+ console.error(chalk.red('Error: No feature in progress. Run codeyam editor 1 first.'));
1017
+ process.exit(1);
1018
+ }
1019
+ const stepFns = {
1020
+ 3: printStep3,
1021
+ 4: printStep4,
1022
+ 5: printStep5,
1023
+ 6: printStep6,
1024
+ 7: printStep7,
1025
+ 8: printStep8,
1026
+ 9: printStep9,
1027
+ 10: printStep10,
1028
+ 11: printStep11,
1029
+ };
1030
+ stepFns[step](root, feature);
1031
+ break;
1032
+ }
1033
+ }
1034
+ },
1035
+ };
1036
+ export default editorCommand;
1037
+ //# sourceMappingURL=editor.js.map