@codeyam/codeyam-cli 0.1.0-staging.a890816 → 0.1.0-staging.aa28063

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 (658) 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 +12 -12
  4. package/analyzer-template/packages/ai/package.json +2 -2
  5. package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +135 -0
  6. package/analyzer-template/packages/ai/src/lib/astScopes/nodeToSource.ts +19 -0
  7. package/analyzer-template/packages/ai/src/lib/astScopes/paths.ts +11 -4
  8. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +36 -9
  9. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.ts +10 -3
  10. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +16 -6
  11. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +0 -33
  12. package/analyzer-template/packages/analyze/index.ts +4 -1
  13. package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +13 -7
  14. package/analyzer-template/packages/analyze/src/lib/asts/index.ts +7 -2
  15. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +28 -2
  16. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +5 -36
  17. package/analyzer-template/packages/analyze/src/lib/files/analyze/findOrCreateEntity.ts +10 -6
  18. package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +9 -12
  19. package/analyzer-template/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.ts +21 -0
  20. package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +82 -10
  21. package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +4 -0
  22. package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +4 -0
  23. package/analyzer-template/packages/analyze/src/lib/files/analyzeNextRoute.ts +8 -3
  24. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +239 -58
  25. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +0 -98
  26. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +1684 -1462
  27. package/analyzer-template/packages/aws/package.json +7 -7
  28. package/analyzer-template/packages/database/package.json +4 -4
  29. package/analyzer-template/packages/database/src/lib/kysely/tables/editorScenariosTable.ts +102 -0
  30. package/analyzer-template/packages/database/src/lib/loadAnalysis.ts +25 -15
  31. package/analyzer-template/packages/database/src/lib/loadEntities.ts +0 -6
  32. package/analyzer-template/packages/database/src/lib/loadEntity.ts +19 -8
  33. package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +0 -65
  34. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts +9 -0
  35. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.d.ts.map +1 -1
  36. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js +104 -0
  37. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -1
  38. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.d.ts.map +1 -1
  39. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js +7 -1
  40. package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js.map +1 -1
  41. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts.map +1 -1
  42. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js +0 -6
  43. package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js.map +1 -1
  44. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.d.ts +4 -1
  45. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.d.ts.map +1 -1
  46. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.js +5 -5
  47. package/analyzer-template/packages/github/dist/database/src/lib/loadEntity.js.map +1 -1
  48. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
  49. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +0 -25
  50. package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js.map +1 -1
  51. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.d.ts +2 -0
  52. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.d.ts.map +1 -1
  53. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.js +2 -0
  54. package/analyzer-template/packages/github/dist/types/src/enums/ProjectFramework.js.map +1 -1
  55. package/analyzer-template/packages/github/package.json +1 -1
  56. package/analyzer-template/packages/types/src/enums/ProjectFramework.ts +2 -0
  57. package/analyzer-template/packages/ui-components/package.json +1 -1
  58. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.d.ts +2 -0
  59. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.d.ts.map +1 -1
  60. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.js +2 -0
  61. package/analyzer-template/packages/utils/dist/types/src/enums/ProjectFramework.js.map +1 -1
  62. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts +3 -1
  63. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts.map +1 -1
  64. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js +22 -1
  65. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  66. package/analyzer-template/packages/utils/src/lib/fs/rsyncCopy.ts +27 -0
  67. package/analyzer-template/project/analyzeFileEntities.ts +26 -0
  68. package/analyzer-template/project/runMultiScenarioServer.ts +26 -3
  69. package/background/src/lib/virtualized/project/analyzeFileEntities.js +22 -0
  70. package/background/src/lib/virtualized/project/analyzeFileEntities.js.map +1 -1
  71. package/background/src/lib/virtualized/project/runMultiScenarioServer.js +23 -3
  72. package/background/src/lib/virtualized/project/runMultiScenarioServer.js.map +1 -1
  73. package/codeyam-cli/src/__tests__/memory-scripts/filter-session.test.js +196 -0
  74. package/codeyam-cli/src/__tests__/memory-scripts/filter-session.test.js.map +1 -0
  75. package/codeyam-cli/src/__tests__/memory-scripts/read-json-field.test.js +114 -0
  76. package/codeyam-cli/src/__tests__/memory-scripts/read-json-field.test.js.map +1 -0
  77. package/codeyam-cli/src/__tests__/memory-scripts/ripgrep-fallback.test.js +149 -0
  78. package/codeyam-cli/src/__tests__/memory-scripts/ripgrep-fallback.test.js.map +1 -0
  79. package/codeyam-cli/src/cli.js +24 -0
  80. package/codeyam-cli/src/cli.js.map +1 -1
  81. package/codeyam-cli/src/commands/__tests__/editor.analyzeImportsArgs.test.js +47 -0
  82. package/codeyam-cli/src/commands/__tests__/editor.analyzeImportsArgs.test.js.map +1 -0
  83. package/codeyam-cli/src/commands/__tests__/editor.auditNoAutoAnalysis.test.js +71 -0
  84. package/codeyam-cli/src/commands/__tests__/editor.auditNoAutoAnalysis.test.js.map +1 -0
  85. package/codeyam-cli/src/commands/__tests__/editor.designSystem.test.js +30 -0
  86. package/codeyam-cli/src/commands/__tests__/editor.designSystem.test.js.map +1 -0
  87. package/codeyam-cli/src/commands/__tests__/editor.isolateArgs.test.js +51 -0
  88. package/codeyam-cli/src/commands/__tests__/editor.isolateArgs.test.js.map +1 -0
  89. package/codeyam-cli/src/commands/__tests__/editor.statePersistence.test.js +55 -0
  90. package/codeyam-cli/src/commands/__tests__/editor.statePersistence.test.js.map +1 -0
  91. package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js +56 -0
  92. package/codeyam-cli/src/commands/__tests__/editor.stepDispatch.test.js.map +1 -0
  93. package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js +137 -47
  94. package/codeyam-cli/src/commands/__tests__/init.gitignore.test.js.map +1 -1
  95. package/codeyam-cli/src/commands/default.js +3 -46
  96. package/codeyam-cli/src/commands/default.js.map +1 -1
  97. package/codeyam-cli/src/commands/editor.js +5802 -526
  98. package/codeyam-cli/src/commands/editor.js.map +1 -1
  99. package/codeyam-cli/src/commands/editorAnalyzeImportsArgs.js +23 -0
  100. package/codeyam-cli/src/commands/editorAnalyzeImportsArgs.js.map +1 -0
  101. package/codeyam-cli/src/commands/editorIsolateArgs.js +25 -0
  102. package/codeyam-cli/src/commands/editorIsolateArgs.js.map +1 -0
  103. package/codeyam-cli/src/commands/init.js +95 -35
  104. package/codeyam-cli/src/commands/init.js.map +1 -1
  105. package/codeyam-cli/src/commands/telemetry.js +37 -0
  106. package/codeyam-cli/src/commands/telemetry.js.map +1 -0
  107. package/codeyam-cli/src/data/designSystems.js +27 -0
  108. package/codeyam-cli/src/data/designSystems.js.map +1 -0
  109. package/codeyam-cli/src/data/techStacks.js +77 -0
  110. package/codeyam-cli/src/data/techStacks.js.map +1 -0
  111. package/codeyam-cli/src/utils/__tests__/analyzerFinalization.test.js +173 -0
  112. package/codeyam-cli/src/utils/__tests__/analyzerFinalization.test.js.map +1 -0
  113. package/codeyam-cli/src/utils/__tests__/backgroundServer.test.js +46 -0
  114. package/codeyam-cli/src/utils/__tests__/backgroundServer.test.js.map +1 -0
  115. package/codeyam-cli/src/utils/__tests__/devServerState.test.js +134 -0
  116. package/codeyam-cli/src/utils/__tests__/devServerState.test.js.map +1 -0
  117. package/codeyam-cli/src/utils/__tests__/editorApi.test.js +181 -0
  118. package/codeyam-cli/src/utils/__tests__/editorApi.test.js.map +1 -0
  119. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +4160 -0
  120. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -0
  121. package/codeyam-cli/src/utils/__tests__/editorBroadcastViewport.test.js +76 -0
  122. package/codeyam-cli/src/utils/__tests__/editorBroadcastViewport.test.js.map +1 -0
  123. package/codeyam-cli/src/utils/__tests__/editorCapture.test.js +93 -0
  124. package/codeyam-cli/src/utils/__tests__/editorCapture.test.js.map +1 -0
  125. package/codeyam-cli/src/utils/__tests__/editorCaptureScenarioSeeding.test.js +137 -0
  126. package/codeyam-cli/src/utils/__tests__/editorCaptureScenarioSeeding.test.js.map +1 -0
  127. package/codeyam-cli/src/utils/__tests__/editorDeleteScenario.test.js +100 -0
  128. package/codeyam-cli/src/utils/__tests__/editorDeleteScenario.test.js.map +1 -0
  129. package/codeyam-cli/src/utils/__tests__/editorDevServer.test.js +304 -0
  130. package/codeyam-cli/src/utils/__tests__/editorDevServer.test.js.map +1 -0
  131. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js +194 -0
  132. package/codeyam-cli/src/utils/__tests__/editorEntityChangeStatus.test.js.map +1 -0
  133. package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js +381 -0
  134. package/codeyam-cli/src/utils/__tests__/editorEntityHelpers.test.js.map +1 -0
  135. package/codeyam-cli/src/utils/__tests__/editorGuardMiddleware.test.js +67 -0
  136. package/codeyam-cli/src/utils/__tests__/editorGuardMiddleware.test.js.map +1 -0
  137. package/codeyam-cli/src/utils/__tests__/editorImageVerifier.test.js +294 -0
  138. package/codeyam-cli/src/utils/__tests__/editorImageVerifier.test.js.map +1 -0
  139. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js +542 -0
  140. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js.map +1 -0
  141. package/codeyam-cli/src/utils/__tests__/editorLoaderHelpers.test.js +594 -0
  142. package/codeyam-cli/src/utils/__tests__/editorLoaderHelpers.test.js.map +1 -0
  143. package/codeyam-cli/src/utils/__tests__/editorMigration.test.js +435 -0
  144. package/codeyam-cli/src/utils/__tests__/editorMigration.test.js.map +1 -0
  145. package/codeyam-cli/src/utils/__tests__/editorMockState.test.js +270 -0
  146. package/codeyam-cli/src/utils/__tests__/editorMockState.test.js.map +1 -0
  147. package/codeyam-cli/src/utils/__tests__/editorPreloadHelpers.test.js +217 -0
  148. package/codeyam-cli/src/utils/__tests__/editorPreloadHelpers.test.js.map +1 -0
  149. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js +361 -0
  150. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js.map +1 -0
  151. package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js +250 -0
  152. package/codeyam-cli/src/utils/__tests__/editorProxySession.test.js.map +1 -0
  153. package/codeyam-cli/src/utils/__tests__/editorRoadmap.test.js +1108 -0
  154. package/codeyam-cli/src/utils/__tests__/editorRoadmap.test.js.map +1 -0
  155. package/codeyam-cli/src/utils/__tests__/editorScenarioLookup.test.js +139 -0
  156. package/codeyam-cli/src/utils/__tests__/editorScenarioLookup.test.js.map +1 -0
  157. package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js +411 -0
  158. package/codeyam-cli/src/utils/__tests__/editorScenarioSwitch.test.js.map +1 -0
  159. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js +1768 -0
  160. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -0
  161. package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js +413 -0
  162. package/codeyam-cli/src/utils/__tests__/editorSeedAdapter.test.js.map +1 -0
  163. package/codeyam-cli/src/utils/__tests__/editorSeedAdapterPrismaValidation.test.js +143 -0
  164. package/codeyam-cli/src/utils/__tests__/editorSeedAdapterPrismaValidation.test.js.map +1 -0
  165. package/codeyam-cli/src/utils/__tests__/editorSessionFilter.test.js +66 -0
  166. package/codeyam-cli/src/utils/__tests__/editorSessionFilter.test.js.map +1 -0
  167. package/codeyam-cli/src/utils/__tests__/editorShouldRevalidate.test.js +53 -0
  168. package/codeyam-cli/src/utils/__tests__/editorShouldRevalidate.test.js.map +1 -0
  169. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js +2121 -0
  170. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js.map +1 -0
  171. package/codeyam-cli/src/utils/__tests__/envFile.test.js +125 -0
  172. package/codeyam-cli/src/utils/__tests__/envFile.test.js.map +1 -0
  173. package/codeyam-cli/src/utils/__tests__/git.editor.test.js +134 -0
  174. package/codeyam-cli/src/utils/__tests__/git.editor.test.js.map +1 -0
  175. package/codeyam-cli/src/utils/__tests__/glossaryAdd.test.js +177 -0
  176. package/codeyam-cli/src/utils/__tests__/glossaryAdd.test.js.map +1 -0
  177. package/codeyam-cli/src/utils/__tests__/handoffContext.test.js +500 -0
  178. package/codeyam-cli/src/utils/__tests__/handoffContext.test.js.map +1 -0
  179. package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js +122 -0
  180. package/codeyam-cli/src/utils/__tests__/journalCaptureStabilization.test.js.map +1 -0
  181. package/codeyam-cli/src/utils/__tests__/manualEntityAnalysis.test.js +302 -0
  182. package/codeyam-cli/src/utils/__tests__/manualEntityAnalysis.test.js.map +1 -0
  183. package/codeyam-cli/src/utils/__tests__/parseRegisterArg.test.js +129 -0
  184. package/codeyam-cli/src/utils/__tests__/parseRegisterArg.test.js.map +1 -0
  185. package/codeyam-cli/src/utils/__tests__/project.test.js +65 -0
  186. package/codeyam-cli/src/utils/__tests__/project.test.js.map +1 -0
  187. package/codeyam-cli/src/utils/__tests__/registerScenarioResult.test.js +127 -0
  188. package/codeyam-cli/src/utils/__tests__/registerScenarioResult.test.js.map +1 -0
  189. package/codeyam-cli/src/utils/__tests__/routePatternMatching.test.js +118 -0
  190. package/codeyam-cli/src/utils/__tests__/routePatternMatching.test.js.map +1 -0
  191. package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js +284 -0
  192. package/codeyam-cli/src/utils/__tests__/scenarioCoverage.test.js.map +1 -0
  193. package/codeyam-cli/src/utils/__tests__/scenarioMarkers.test.js +121 -0
  194. package/codeyam-cli/src/utils/__tests__/scenarioMarkers.test.js.map +1 -0
  195. package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js +672 -0
  196. package/codeyam-cli/src/utils/__tests__/scenariosManifest.test.js.map +1 -0
  197. package/codeyam-cli/src/utils/__tests__/screenshotHash.test.js +84 -0
  198. package/codeyam-cli/src/utils/__tests__/screenshotHash.test.js.map +1 -0
  199. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +26 -5
  200. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  201. package/codeyam-cli/src/utils/__tests__/telemetry.test.js +159 -0
  202. package/codeyam-cli/src/utils/__tests__/telemetry.test.js.map +1 -0
  203. package/codeyam-cli/src/utils/__tests__/templateConsistency.test.js +51 -0
  204. package/codeyam-cli/src/utils/__tests__/templateConsistency.test.js.map +1 -0
  205. package/codeyam-cli/src/utils/__tests__/testRunner.test.js +216 -0
  206. package/codeyam-cli/src/utils/__tests__/testRunner.test.js.map +1 -0
  207. package/codeyam-cli/src/utils/__tests__/webappDetection.test.js +148 -0
  208. package/codeyam-cli/src/utils/__tests__/webappDetection.test.js.map +1 -0
  209. package/codeyam-cli/src/utils/analysisRunner.js +39 -8
  210. package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
  211. package/codeyam-cli/src/utils/analyzer.js +19 -0
  212. package/codeyam-cli/src/utils/analyzer.js.map +1 -1
  213. package/codeyam-cli/src/utils/analyzerFinalization.js +100 -0
  214. package/codeyam-cli/src/utils/analyzerFinalization.js.map +1 -0
  215. package/codeyam-cli/src/utils/backgroundServer.js +95 -19
  216. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  217. package/codeyam-cli/src/utils/buildFlags.js +4 -0
  218. package/codeyam-cli/src/utils/buildFlags.js.map +1 -0
  219. package/codeyam-cli/src/utils/database.js +37 -2
  220. package/codeyam-cli/src/utils/database.js.map +1 -1
  221. package/codeyam-cli/src/utils/designSystemShowcase.js +810 -0
  222. package/codeyam-cli/src/utils/designSystemShowcase.js.map +1 -0
  223. package/codeyam-cli/src/utils/devServerState.js +71 -0
  224. package/codeyam-cli/src/utils/devServerState.js.map +1 -0
  225. package/codeyam-cli/src/utils/editorApi.js +95 -0
  226. package/codeyam-cli/src/utils/editorApi.js.map +1 -0
  227. package/codeyam-cli/src/utils/editorAudit.js +849 -0
  228. package/codeyam-cli/src/utils/editorAudit.js.map +1 -0
  229. package/codeyam-cli/src/utils/editorBroadcastViewport.js +26 -0
  230. package/codeyam-cli/src/utils/editorBroadcastViewport.js.map +1 -0
  231. package/codeyam-cli/src/utils/editorCapture.js +102 -0
  232. package/codeyam-cli/src/utils/editorCapture.js.map +1 -0
  233. package/codeyam-cli/src/utils/editorDeleteScenario.js +67 -0
  234. package/codeyam-cli/src/utils/editorDeleteScenario.js.map +1 -0
  235. package/codeyam-cli/src/utils/editorDevServer.js +197 -0
  236. package/codeyam-cli/src/utils/editorDevServer.js.map +1 -0
  237. package/codeyam-cli/src/utils/editorEntityChangeStatus.js +50 -0
  238. package/codeyam-cli/src/utils/editorEntityChangeStatus.js.map +1 -0
  239. package/codeyam-cli/src/utils/editorEntityHelpers.js +144 -0
  240. package/codeyam-cli/src/utils/editorEntityHelpers.js.map +1 -0
  241. package/codeyam-cli/src/utils/editorGuard.js +36 -0
  242. package/codeyam-cli/src/utils/editorGuard.js.map +1 -0
  243. package/codeyam-cli/src/utils/editorImageVerifier.js +155 -0
  244. package/codeyam-cli/src/utils/editorImageVerifier.js.map +1 -0
  245. package/codeyam-cli/src/utils/editorJournal.js +225 -0
  246. package/codeyam-cli/src/utils/editorJournal.js.map +1 -0
  247. package/codeyam-cli/src/utils/editorLoaderHelpers.js +152 -0
  248. package/codeyam-cli/src/utils/editorLoaderHelpers.js.map +1 -0
  249. package/codeyam-cli/src/utils/editorMigration.js +224 -0
  250. package/codeyam-cli/src/utils/editorMigration.js.map +1 -0
  251. package/codeyam-cli/src/utils/editorMockState.js +248 -0
  252. package/codeyam-cli/src/utils/editorMockState.js.map +1 -0
  253. package/codeyam-cli/src/utils/editorPreloadHelpers.js +135 -0
  254. package/codeyam-cli/src/utils/editorPreloadHelpers.js.map +1 -0
  255. package/codeyam-cli/src/utils/editorPreview.js +139 -0
  256. package/codeyam-cli/src/utils/editorPreview.js.map +1 -0
  257. package/codeyam-cli/src/utils/editorRecapture.js +109 -0
  258. package/codeyam-cli/src/utils/editorRecapture.js.map +1 -0
  259. package/codeyam-cli/src/utils/editorRoadmap.js +574 -0
  260. package/codeyam-cli/src/utils/editorRoadmap.js.map +1 -0
  261. package/codeyam-cli/src/utils/editorScenarioSwitch.js +149 -0
  262. package/codeyam-cli/src/utils/editorScenarioSwitch.js.map +1 -0
  263. package/codeyam-cli/src/utils/editorScenarios.js +687 -0
  264. package/codeyam-cli/src/utils/editorScenarios.js.map +1 -0
  265. package/codeyam-cli/src/utils/editorSeedAdapter.js +475 -0
  266. package/codeyam-cli/src/utils/editorSeedAdapter.js.map +1 -0
  267. package/codeyam-cli/src/utils/editorShouldRevalidate.js +21 -0
  268. package/codeyam-cli/src/utils/editorShouldRevalidate.js.map +1 -0
  269. package/codeyam-cli/src/utils/entityChangeStatus.js +394 -0
  270. package/codeyam-cli/src/utils/entityChangeStatus.js.map +1 -0
  271. package/codeyam-cli/src/utils/entityChangeStatus.server.js +227 -0
  272. package/codeyam-cli/src/utils/entityChangeStatus.server.js.map +1 -0
  273. package/codeyam-cli/src/utils/envFile.js +90 -0
  274. package/codeyam-cli/src/utils/envFile.js.map +1 -0
  275. package/codeyam-cli/src/utils/fileWatcher.js +38 -0
  276. package/codeyam-cli/src/utils/fileWatcher.js.map +1 -1
  277. package/codeyam-cli/src/utils/git.js +51 -0
  278. package/codeyam-cli/src/utils/git.js.map +1 -1
  279. package/codeyam-cli/src/utils/glossaryAdd.js +74 -0
  280. package/codeyam-cli/src/utils/glossaryAdd.js.map +1 -0
  281. package/codeyam-cli/src/utils/handoffContext.js +257 -0
  282. package/codeyam-cli/src/utils/handoffContext.js.map +1 -0
  283. package/codeyam-cli/src/utils/install-skills.js +78 -23
  284. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  285. package/codeyam-cli/src/utils/manualEntityAnalysis.js +196 -0
  286. package/codeyam-cli/src/utils/manualEntityAnalysis.js.map +1 -0
  287. package/codeyam-cli/src/utils/parseRegisterArg.js +31 -0
  288. package/codeyam-cli/src/utils/parseRegisterArg.js.map +1 -0
  289. package/codeyam-cli/src/utils/progress.js +2 -2
  290. package/codeyam-cli/src/utils/progress.js.map +1 -1
  291. package/codeyam-cli/src/utils/project.js +15 -5
  292. package/codeyam-cli/src/utils/project.js.map +1 -1
  293. package/codeyam-cli/src/utils/queue/__tests__/job.interactiveStart.test.js +159 -0
  294. package/codeyam-cli/src/utils/queue/__tests__/job.interactiveStart.test.js.map +1 -0
  295. package/codeyam-cli/src/utils/queue/job.js +35 -6
  296. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  297. package/codeyam-cli/src/utils/registerScenarioResult.js +52 -0
  298. package/codeyam-cli/src/utils/registerScenarioResult.js.map +1 -0
  299. package/codeyam-cli/src/utils/routePatternMatching.js +129 -0
  300. package/codeyam-cli/src/utils/routePatternMatching.js.map +1 -0
  301. package/codeyam-cli/src/utils/scenarioCoverage.js +77 -0
  302. package/codeyam-cli/src/utils/scenarioCoverage.js.map +1 -0
  303. package/codeyam-cli/src/utils/scenarioMarkers.js +134 -0
  304. package/codeyam-cli/src/utils/scenarioMarkers.js.map +1 -0
  305. package/codeyam-cli/src/utils/scenariosManifest.js +313 -0
  306. package/codeyam-cli/src/utils/scenariosManifest.js.map +1 -0
  307. package/codeyam-cli/src/utils/screenshotHash.js +26 -0
  308. package/codeyam-cli/src/utils/screenshotHash.js.map +1 -0
  309. package/codeyam-cli/src/utils/serverState.js +30 -0
  310. package/codeyam-cli/src/utils/serverState.js.map +1 -1
  311. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +47 -16
  312. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  313. package/codeyam-cli/src/utils/simulationGateMiddleware.js +17 -1
  314. package/codeyam-cli/src/utils/simulationGateMiddleware.js.map +1 -1
  315. package/codeyam-cli/src/utils/slugUtils.js +25 -0
  316. package/codeyam-cli/src/utils/slugUtils.js.map +1 -0
  317. package/codeyam-cli/src/utils/syncMocksMiddleware.js +2 -2
  318. package/codeyam-cli/src/utils/syncMocksMiddleware.js.map +1 -1
  319. package/codeyam-cli/src/utils/techStackConfig.js +38 -0
  320. package/codeyam-cli/src/utils/techStackConfig.js.map +1 -0
  321. package/codeyam-cli/src/utils/techStackConfig.test.js +85 -0
  322. package/codeyam-cli/src/utils/techStackConfig.test.js.map +1 -0
  323. package/codeyam-cli/src/utils/telemetry.js +106 -0
  324. package/codeyam-cli/src/utils/telemetry.js.map +1 -0
  325. package/codeyam-cli/src/utils/telemetryMiddleware.js +22 -0
  326. package/codeyam-cli/src/utils/telemetryMiddleware.js.map +1 -0
  327. package/codeyam-cli/src/utils/testResultCache.js +53 -0
  328. package/codeyam-cli/src/utils/testResultCache.js.map +1 -0
  329. package/codeyam-cli/src/utils/testResultCache.server.js +81 -0
  330. package/codeyam-cli/src/utils/testResultCache.server.js.map +1 -0
  331. package/codeyam-cli/src/utils/testResultCache.server.test.js +187 -0
  332. package/codeyam-cli/src/utils/testResultCache.server.test.js.map +1 -0
  333. package/codeyam-cli/src/utils/testResultCache.test.js +230 -0
  334. package/codeyam-cli/src/utils/testResultCache.test.js.map +1 -0
  335. package/codeyam-cli/src/utils/testRunner.js +194 -2
  336. package/codeyam-cli/src/utils/testRunner.js.map +1 -1
  337. package/codeyam-cli/src/utils/webappDetection.js +25 -2
  338. package/codeyam-cli/src/utils/webappDetection.js.map +1 -1
  339. package/codeyam-cli/src/webserver/__tests__/api.interactive-switch-scenario.test.js +99 -0
  340. package/codeyam-cli/src/webserver/__tests__/api.interactive-switch-scenario.test.js.map +1 -0
  341. package/codeyam-cli/src/webserver/__tests__/buildPtyEnv.test.js +129 -0
  342. package/codeyam-cli/src/webserver/__tests__/buildPtyEnv.test.js.map +1 -0
  343. package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js +107 -0
  344. package/codeyam-cli/src/webserver/__tests__/clientErrors.test.js.map +1 -0
  345. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js +762 -0
  346. package/codeyam-cli/src/webserver/__tests__/editorProxy.test.js.map +1 -0
  347. package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js +315 -0
  348. package/codeyam-cli/src/webserver/__tests__/idleDetector.test.js.map +1 -0
  349. package/codeyam-cli/src/webserver/__tests__/stripClaudeCommand.test.js +135 -0
  350. package/codeyam-cli/src/webserver/__tests__/stripClaudeCommand.test.js.map +1 -0
  351. package/codeyam-cli/src/webserver/app/lib/clientErrors.js +86 -0
  352. package/codeyam-cli/src/webserver/app/lib/clientErrors.js.map +1 -0
  353. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  354. package/codeyam-cli/src/webserver/app/lib/git.js +397 -0
  355. package/codeyam-cli/src/webserver/app/lib/git.js.map +1 -0
  356. package/codeyam-cli/src/webserver/app/routes/api.interactive-switch-scenario.js +34 -0
  357. package/codeyam-cli/src/webserver/app/routes/api.interactive-switch-scenario.js.map +1 -0
  358. package/codeyam-cli/src/webserver/app/types/editor.js +8 -0
  359. package/codeyam-cli/src/webserver/app/types/editor.js.map +1 -0
  360. package/codeyam-cli/src/webserver/backgroundServer.js +60 -61
  361. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  362. package/codeyam-cli/src/webserver/build/client/assets/CopyButton-DTBZZfSk.js +1 -0
  363. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-C76mRRiF.js → EntityItem-BxclONWq.js} +5 -5
  364. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeBadge-CQgyEGV-.js +1 -0
  365. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-CobE682z.js → EntityTypeIcon-BsnEOJZ_.js} +9 -9
  366. package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-ByaELMbv.js +1 -0
  367. package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-6WjVfhxX.js +25 -0
  368. package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-ChX-Hp7W.js +3 -0
  369. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-BU_OAEMP.js → LoadingDots-By5zI316.js} +1 -1
  370. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-ceAyBX-H.js → LogViewer-C-9zQdXg.js} +3 -3
  371. package/codeyam-cli/src/webserver/build/client/assets/MiniClaudeChat-Bs2_Oua4.js +36 -0
  372. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-djPLI-WV.js → ReportIssueModal-DQsceHVv.js} +4 -4
  373. package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-DThcm_9M.js +1 -0
  374. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-B76aig_2.js → ScenarioViewer-Cl4oOA3A.js} +3 -3
  375. package/codeyam-cli/src/webserver/build/client/assets/Spinner-CIil5-gb.js +34 -0
  376. package/codeyam-cli/src/webserver/build/client/assets/TruncatedFilePath-CK7-NaPZ.js +1 -0
  377. package/codeyam-cli/src/webserver/build/client/assets/ViewportInspectBar-BqkA9zyZ.js +1 -0
  378. package/codeyam-cli/src/webserver/build/client/assets/{_index-C96V0n15.js → _index-DnOgyseQ.js} +4 -4
  379. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BpKzcsJz.js → activity.(_tab)-DqM9hbNE.js} +8 -8
  380. package/codeyam-cli/src/webserver/build/client/assets/addon-canvas-DpzMmAy5.js +1 -0
  381. package/codeyam-cli/src/webserver/build/client/assets/addon-fit-YJmn1quW.js +12 -0
  382. package/codeyam-cli/src/webserver/build/client/assets/{addon-web-links-Duc5hnl7.js → addon-web-links-C58dYPwR.js} +1 -1
  383. package/codeyam-cli/src/webserver/build/client/assets/addon-webgl-DI8QOUvO.js +58 -0
  384. package/codeyam-cli/src/webserver/build/client/assets/{agent-transcripts-D9hemwl6.js → agent-transcripts-B8NCeOrm.js} +7 -7
  385. package/codeyam-cli/src/webserver/build/client/assets/api.editor-audit-l0sNRNKZ.js +1 -0
  386. package/codeyam-cli/src/webserver/build/client/assets/api.editor-database-verify-l0sNRNKZ.js +1 -0
  387. package/codeyam-cli/src/webserver/build/client/assets/api.editor-file-diff-l0sNRNKZ.js +1 -0
  388. package/codeyam-cli/src/webserver/build/client/assets/api.editor-file-l0sNRNKZ.js +1 -0
  389. package/codeyam-cli/src/webserver/build/client/assets/api.editor-github-verify-l0sNRNKZ.js +1 -0
  390. package/codeyam-cli/src/webserver/build/client/assets/api.editor-handoff-l0sNRNKZ.js +1 -0
  391. package/codeyam-cli/src/webserver/build/client/assets/api.editor-hosting-verify-l0sNRNKZ.js +1 -0
  392. package/codeyam-cli/src/webserver/build/client/assets/api.editor-load-commit-l0sNRNKZ.js +1 -0
  393. package/codeyam-cli/src/webserver/build/client/assets/api.editor-project-info-l0sNRNKZ.js +1 -0
  394. package/codeyam-cli/src/webserver/build/client/assets/api.editor-recapture-stale-l0sNRNKZ.js +1 -0
  395. package/codeyam-cli/src/webserver/build/client/assets/api.editor-rename-scenario-l0sNRNKZ.js +1 -0
  396. package/codeyam-cli/src/webserver/build/client/assets/api.editor-roadmap-l0sNRNKZ.js +1 -0
  397. package/codeyam-cli/src/webserver/build/client/assets/api.editor-save-scenario-data-l0sNRNKZ.js +1 -0
  398. package/codeyam-cli/src/webserver/build/client/assets/api.editor-save-seed-state-l0sNRNKZ.js +1 -0
  399. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-coverage-l0sNRNKZ.js +1 -0
  400. package/codeyam-cli/src/webserver/build/client/assets/api.editor-scenario-prompt-l0sNRNKZ.js +1 -0
  401. package/codeyam-cli/src/webserver/build/client/assets/api.editor-schema-l0sNRNKZ.js +1 -0
  402. package/codeyam-cli/src/webserver/build/client/assets/api.editor-session-l0sNRNKZ.js +1 -0
  403. package/codeyam-cli/src/webserver/build/client/assets/api.editor-verify-routes-l0sNRNKZ.js +1 -0
  404. package/codeyam-cli/src/webserver/build/client/assets/api.interactive-switch-scenario-l0sNRNKZ.js +1 -0
  405. package/codeyam-cli/src/webserver/build/client/assets/{book-open-D_nMCFmP.js → book-open-BFSIqZgO.js} +2 -2
  406. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-BH2h1Ea2.js → chevron-down-B9fDzFVh.js} +2 -2
  407. package/codeyam-cli/src/webserver/build/client/assets/chunk-UVKPFVEO-Bmq2apuh.js +43 -0
  408. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-DyIKORY6.js → circle-check-DLPObLUx.js} +2 -2
  409. package/codeyam-cli/src/webserver/build/client/assets/{copy-NDbZjXao.js → copy-DXEmO0TD.js} +3 -3
  410. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-BwyFiRot.js +41 -0
  411. package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-Coe5NhbS.js +1 -0
  412. package/codeyam-cli/src/webserver/build/client/assets/{cy-logo-cli-CCKUIm0S.svg → cy-logo-cli-DoA97ML3.svg} +2 -2
  413. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-iRhRIFlp.js +1 -0
  414. package/codeyam-cli/src/webserver/build/client/assets/editor._tab-BZPBzV73.js +1 -0
  415. package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-DOXe0Qx7.js +161 -0
  416. package/codeyam-cli/src/webserver/build/client/assets/editorPreview-C6fEYHrh.js +41 -0
  417. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-CrjR3zZW.js → entity._sha._-pc-vc6wO.js} +14 -13
  418. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-C8AyYgYT.js +6 -0
  419. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-DziaVQX1.js +6 -0
  420. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-BTcpgIpC.js +6 -0
  421. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-BMvVHNXU.js → entity._sha_.edit._scenarioId-D_O_ajfZ.js} +2 -2
  422. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-DTvKq3TY.js → entry.client-j1Vi0bco.js} +6 -6
  423. package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-Daa96Fr1.js +1 -0
  424. package/codeyam-cli/src/webserver/build/client/assets/files-kuny2Q_s.js +1 -0
  425. package/codeyam-cli/src/webserver/build/client/assets/git-DgCZPMie.js +1 -0
  426. package/codeyam-cli/src/webserver/build/client/assets/globals-L-aUIeux.css +1 -0
  427. package/codeyam-cli/src/webserver/build/client/assets/{index-BcvgDzbZ.js → index-BliGSSpl.js} +1 -1
  428. package/codeyam-cli/src/webserver/build/client/assets/index-SqjQKTdH.js +15 -0
  429. package/codeyam-cli/src/webserver/build/client/assets/{index-10oVnAAH.js → index-vyrZD2g4.js} +1 -1
  430. package/codeyam-cli/src/webserver/build/client/assets/jsx-runtime-D_zvdyIk.js +9 -0
  431. package/codeyam-cli/src/webserver/build/client/assets/labs-c3yLxSEp.js +1 -0
  432. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-BAXYRVEO.js → loader-circle-D-q28GLF.js} +2 -2
  433. package/codeyam-cli/src/webserver/build/client/assets/manifest-30c44d84.js +1 -0
  434. package/codeyam-cli/src/webserver/build/client/assets/memory-CEWIUC4t.js +101 -0
  435. package/codeyam-cli/src/webserver/build/client/assets/{pause-DTAcYxBt.js → pause-BP6fitdh.js} +3 -3
  436. package/codeyam-cli/src/webserver/build/client/assets/root-CLedrjXQ.js +80 -0
  437. package/codeyam-cli/src/webserver/build/client/assets/{search-fKo7v0Zo.js → search-BooqacKS.js} +2 -2
  438. package/codeyam-cli/src/webserver/build/client/assets/settings-BM0nbryO.js +1 -0
  439. package/codeyam-cli/src/webserver/build/client/assets/simulations-ovy6FjRY.js +1 -0
  440. package/codeyam-cli/src/webserver/build/client/assets/{terminal-BG4heKCG.js → terminal-DHemCJIs.js} +3 -3
  441. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-DtSmdtM4.js → triangle-alert-D87ekDl8.js} +2 -2
  442. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-Dk0Tciqg.js +1 -0
  443. package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-C8QvIe05.js +2 -0
  444. package/codeyam-cli/src/webserver/build/client/assets/useReportContext-jkCytuYz.js +1 -0
  445. package/codeyam-cli/src/webserver/build/client/assets/useToast-BgqkixU9.js +1 -0
  446. package/codeyam-cli/src/webserver/build/client/assets/xterm-BqvuqXEL.js +27 -0
  447. package/codeyam-cli/src/webserver/build/client/sound-test.html +98 -0
  448. package/codeyam-cli/src/webserver/build/server/assets/analysisRunner-CuR5TvUx.js +16 -0
  449. package/codeyam-cli/src/webserver/build/server/assets/index-D4MWAsqb.js +1 -0
  450. package/codeyam-cli/src/webserver/build/server/assets/init-JObA4lXD.js +14 -0
  451. package/codeyam-cli/src/webserver/build/server/assets/progress-CHTtrxFG.js +1 -0
  452. package/codeyam-cli/src/webserver/build/server/assets/server-build-i8OXK4oL.js +765 -0
  453. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  454. package/codeyam-cli/src/webserver/build-info.json +5 -5
  455. package/codeyam-cli/src/webserver/editorProxy.js +881 -52
  456. package/codeyam-cli/src/webserver/editorProxy.js.map +1 -1
  457. package/codeyam-cli/src/webserver/idleDetector.js +130 -0
  458. package/codeyam-cli/src/webserver/idleDetector.js.map +1 -0
  459. package/codeyam-cli/src/webserver/mockStateEvents.js +28 -0
  460. package/codeyam-cli/src/webserver/mockStateEvents.js.map +1 -0
  461. package/codeyam-cli/src/webserver/public/sound-test.html +98 -0
  462. package/codeyam-cli/src/webserver/scripts/codeyam-preload.mjs +414 -0
  463. package/codeyam-cli/src/webserver/scripts/journalCapture.ts +147 -4
  464. package/codeyam-cli/src/webserver/server.js +281 -12
  465. package/codeyam-cli/src/webserver/server.js.map +1 -1
  466. package/codeyam-cli/src/webserver/terminalServer.js +433 -157
  467. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
  468. package/codeyam-cli/templates/__tests__/editor-step-hook.prompt-capture.test.ts +118 -0
  469. package/codeyam-cli/templates/chrome-extension-react/EXTENSION_SETUP.md +75 -0
  470. package/codeyam-cli/templates/chrome-extension-react/README.md +46 -0
  471. package/codeyam-cli/templates/chrome-extension-react/gitignore +15 -0
  472. package/codeyam-cli/templates/chrome-extension-react/index.html +12 -0
  473. package/codeyam-cli/templates/chrome-extension-react/package.json +27 -0
  474. package/codeyam-cli/templates/chrome-extension-react/popup.html +12 -0
  475. package/codeyam-cli/templates/chrome-extension-react/public/manifest.json +15 -0
  476. package/codeyam-cli/templates/chrome-extension-react/src/background/service-worker.ts +7 -0
  477. package/codeyam-cli/templates/chrome-extension-react/src/globals.css +6 -0
  478. package/codeyam-cli/templates/chrome-extension-react/src/lib/storage.ts +37 -0
  479. package/codeyam-cli/templates/chrome-extension-react/src/popup/App.tsx +12 -0
  480. package/codeyam-cli/templates/chrome-extension-react/src/popup/main.tsx +10 -0
  481. package/codeyam-cli/templates/chrome-extension-react/tsconfig.json +24 -0
  482. package/codeyam-cli/templates/chrome-extension-react/vite.config.ts +41 -0
  483. package/codeyam-cli/templates/codeyam-editor-claude.md +86 -5
  484. package/codeyam-cli/templates/codeyam-editor-codex.md +61 -0
  485. package/codeyam-cli/templates/codeyam-editor-gemini.md +59 -0
  486. package/codeyam-cli/templates/codeyam-editor-reference.md +216 -0
  487. package/codeyam-cli/templates/design-systems/clean-dashboard-design-system.md +255 -0
  488. package/codeyam-cli/templates/design-systems/editorial-design-system.md +267 -0
  489. package/codeyam-cli/templates/design-systems/mono-brutalist-design-system.md +256 -0
  490. package/codeyam-cli/templates/design-systems/neo-brutalist-design-system.md +294 -0
  491. package/codeyam-cli/templates/editor-step-hook.py +262 -39
  492. package/codeyam-cli/templates/expo-react-native/MOBILE_SETUP.md +288 -0
  493. package/codeyam-cli/templates/expo-react-native/README.md +41 -0
  494. package/codeyam-cli/templates/expo-react-native/__tests__/.gitkeep +0 -0
  495. package/codeyam-cli/templates/expo-react-native/app/_layout.tsx +15 -0
  496. package/codeyam-cli/templates/expo-react-native/app/index.tsx +36 -0
  497. package/codeyam-cli/templates/expo-react-native/app.json +29 -0
  498. package/codeyam-cli/templates/expo-react-native/babel.config.js +10 -0
  499. package/codeyam-cli/templates/expo-react-native/gitignore +14 -0
  500. package/codeyam-cli/templates/expo-react-native/global.css +10 -0
  501. package/codeyam-cli/templates/expo-react-native/lib/storage.ts +32 -0
  502. package/codeyam-cli/templates/expo-react-native/lib/theme.ts +73 -0
  503. package/codeyam-cli/templates/expo-react-native/metro.config.js +6 -0
  504. package/codeyam-cli/templates/expo-react-native/nativewind-env.d.ts +1 -0
  505. package/codeyam-cli/templates/expo-react-native/package.json +54 -0
  506. package/codeyam-cli/templates/expo-react-native/patches/expo-modules-autolinking+3.0.24.patch +29 -0
  507. package/codeyam-cli/templates/expo-react-native/tailwind.config.js +10 -0
  508. package/codeyam-cli/templates/expo-react-native/tsconfig.json +10 -0
  509. package/codeyam-cli/templates/isolation-route/expo-router.tsx.template +54 -0
  510. package/codeyam-cli/templates/nextjs-prisma-sqlite/AUTH_PATTERNS.md +308 -0
  511. package/codeyam-cli/templates/nextjs-prisma-sqlite/AUTH_UPGRADE.md +304 -0
  512. package/codeyam-cli/templates/nextjs-prisma-sqlite/DATABASE.md +126 -0
  513. package/codeyam-cli/templates/nextjs-prisma-sqlite/FEATURE_PATTERNS.md +37 -0
  514. package/codeyam-cli/templates/nextjs-prisma-sqlite/README.md +53 -0
  515. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/codeyam-isolate/layout.tsx +12 -0
  516. package/codeyam-cli/templates/nextjs-prisma-sqlite/app/lib/prisma.ts +9 -4
  517. package/codeyam-cli/templates/nextjs-prisma-sqlite/env +4 -0
  518. package/codeyam-cli/templates/nextjs-prisma-sqlite/gitignore +22 -0
  519. package/codeyam-cli/templates/nextjs-prisma-sqlite/package.json +6 -2
  520. package/codeyam-cli/templates/nextjs-prisma-sqlite/prisma/seed.ts +4 -1
  521. package/codeyam-cli/templates/nextjs-prisma-sqlite/seed-adapter.ts +140 -0
  522. package/codeyam-cli/templates/nextjs-prisma-sqlite/vitest.config.ts +13 -0
  523. package/codeyam-cli/templates/nextjs-prisma-supabase/README.md +52 -0
  524. package/codeyam-cli/templates/{nextjs-prisma-sqlite/PRISMA_SETUP.md → nextjs-prisma-supabase/SUPABASE_SETUP.md} +37 -17
  525. package/codeyam-cli/templates/nextjs-prisma-supabase/app/api/todos/route.ts +17 -0
  526. package/codeyam-cli/templates/nextjs-prisma-supabase/app/globals.css +26 -0
  527. package/codeyam-cli/templates/nextjs-prisma-supabase/app/layout.tsx +34 -0
  528. package/codeyam-cli/templates/nextjs-prisma-supabase/app/lib/prisma.ts +20 -0
  529. package/codeyam-cli/templates/nextjs-prisma-supabase/app/lib/supabase.ts +12 -0
  530. package/codeyam-cli/templates/nextjs-prisma-supabase/app/page.tsx +10 -0
  531. package/codeyam-cli/templates/nextjs-prisma-supabase/env +9 -0
  532. package/codeyam-cli/templates/nextjs-prisma-supabase/eslint.config.mjs +11 -0
  533. package/codeyam-cli/templates/nextjs-prisma-supabase/gitignore +40 -0
  534. package/codeyam-cli/templates/nextjs-prisma-supabase/next.config.ts +11 -0
  535. package/codeyam-cli/templates/nextjs-prisma-supabase/package.json +37 -0
  536. package/codeyam-cli/templates/nextjs-prisma-supabase/postcss.config.mjs +7 -0
  537. package/codeyam-cli/templates/nextjs-prisma-supabase/prisma/schema.prisma +27 -0
  538. package/codeyam-cli/templates/nextjs-prisma-supabase/prisma/seed.ts +39 -0
  539. package/codeyam-cli/templates/nextjs-prisma-supabase/prisma.config.ts +12 -0
  540. package/codeyam-cli/templates/nextjs-prisma-supabase/tsconfig.json +34 -0
  541. package/codeyam-cli/templates/seed-adapters/supabase.ts +475 -0
  542. package/codeyam-cli/templates/{codeyam-dev-mode.md → skills/codeyam-dev-mode/SKILL.md} +3 -3
  543. package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +244 -0
  544. package/codeyam-cli/templates/{codeyam-memory.md → skills/codeyam-memory/SKILL.md} +215 -0
  545. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/deprecated-prompt.md +100 -0
  546. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/detect-deprecated-patterns.mjs +139 -0
  547. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/find-exports.mjs +52 -0
  548. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/misleading-api-prompt.md +117 -0
  549. package/codeyam-cli/templates/skills/codeyam-memory/scripts/lib/read-json-field.mjs +61 -0
  550. package/codeyam-cli/templates/skills/codeyam-memory/scripts/lib/ripgrep-fallback.mjs +155 -0
  551. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/analyze-prompt.md +46 -0
  552. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/cleanup.mjs +13 -0
  553. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/filter-session.mjs +95 -0
  554. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/preprocess.mjs +160 -0
  555. package/package.json +16 -10
  556. package/packages/ai/src/lib/astScopes/methodSemantics.js +99 -0
  557. package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
  558. package/packages/ai/src/lib/astScopes/nodeToSource.js +16 -0
  559. package/packages/ai/src/lib/astScopes/nodeToSource.js.map +1 -1
  560. package/packages/ai/src/lib/astScopes/paths.js +12 -3
  561. package/packages/ai/src/lib/astScopes/paths.js.map +1 -1
  562. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +27 -10
  563. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  564. package/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.js +9 -2
  565. package/packages/ai/src/lib/dataStructure/equivalencyManagers/ParentScopeManager.js.map +1 -1
  566. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +14 -4
  567. package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
  568. package/packages/ai/src/lib/generateExecutionFlows.js +0 -11
  569. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
  570. package/packages/analyze/index.js +1 -1
  571. package/packages/analyze/index.js.map +1 -1
  572. package/packages/analyze/src/lib/ProjectAnalyzer.js +10 -4
  573. package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
  574. package/packages/analyze/src/lib/asts/index.js +4 -2
  575. package/packages/analyze/src/lib/asts/index.js.map +1 -1
  576. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +16 -2
  577. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  578. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +6 -26
  579. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  580. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js +3 -2
  581. package/packages/analyze/src/lib/files/analyze/findOrCreateEntity.js.map +1 -1
  582. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +9 -7
  583. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
  584. package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js +14 -0
  585. package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js.map +1 -1
  586. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +44 -11
  587. package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
  588. package/packages/analyze/src/lib/files/analyzeChange.js +1 -0
  589. package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
  590. package/packages/analyze/src/lib/files/analyzeInitial.js +1 -0
  591. package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
  592. package/packages/analyze/src/lib/files/analyzeNextRoute.js +5 -1
  593. package/packages/analyze/src/lib/files/analyzeNextRoute.js.map +1 -1
  594. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +120 -28
  595. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  596. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +0 -40
  597. package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -1
  598. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +1368 -1193
  599. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  600. package/packages/database/src/lib/kysely/tables/editorScenariosTable.js +104 -0
  601. package/packages/database/src/lib/kysely/tables/editorScenariosTable.js.map +1 -1
  602. package/packages/database/src/lib/loadAnalysis.js +7 -1
  603. package/packages/database/src/lib/loadAnalysis.js.map +1 -1
  604. package/packages/database/src/lib/loadEntities.js +0 -6
  605. package/packages/database/src/lib/loadEntities.js.map +1 -1
  606. package/packages/database/src/lib/loadEntity.js +5 -5
  607. package/packages/database/src/lib/loadEntity.js.map +1 -1
  608. package/packages/database/src/lib/updateCommitMetadata.js +0 -25
  609. package/packages/database/src/lib/updateCommitMetadata.js.map +1 -1
  610. package/packages/types/src/enums/ProjectFramework.js +2 -0
  611. package/packages/types/src/enums/ProjectFramework.js.map +1 -1
  612. package/packages/utils/src/lib/fs/rsyncCopy.js +22 -1
  613. package/packages/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  614. package/scripts/npm-post-install.cjs +34 -0
  615. package/codeyam-cli/src/webserver/build/client/assets/CopyButton-DmJveP3T.js +0 -1
  616. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeBadge-g3saevPb.js +0 -1
  617. package/codeyam-cli/src/webserver/build/client/assets/InlineSpinner-Bu6c6aDe.js +0 -1
  618. package/codeyam-cli/src/webserver/build/client/assets/InteractivePreview-DYFW3lDD.js +0 -25
  619. package/codeyam-cli/src/webserver/build/client/assets/LibraryFunctionPreview-DLeucoVX.js +0 -3
  620. package/codeyam-cli/src/webserver/build/client/assets/SafeScreenshot-BED4B6sP.js +0 -1
  621. package/codeyam-cli/src/webserver/build/client/assets/Spinner-Bb5uFQ5V.js +0 -34
  622. package/codeyam-cli/src/webserver/build/client/assets/Terminal-CcG8YTLx.js +0 -41
  623. package/codeyam-cli/src/webserver/build/client/assets/TruncatedFilePath-C8OKAR5x.js +0 -1
  624. package/codeyam-cli/src/webserver/build/client/assets/addon-fit-CUXOrorO.js +0 -1
  625. package/codeyam-cli/src/webserver/build/client/assets/chunk-JZWAC4HX-C4pqxYJB.js +0 -51
  626. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CMT1jU2q.js +0 -21
  627. package/codeyam-cli/src/webserver/build/client/assets/cy-logo-cli-DcX-ZS3p.js +0 -1
  628. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BiM6z3Do.js +0 -1
  629. package/codeyam-cli/src/webserver/build/client/assets/editor-W_IGJ2Kd.js +0 -7
  630. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-D6SEzMCu.js +0 -6
  631. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.fullscreen-C28BiQzt.js +0 -6
  632. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.create-scenario-p9hhkjJM.js +0 -6
  633. package/codeyam-cli/src/webserver/build/client/assets/fileTableUtils-cPo8LiG3.js +0 -1
  634. package/codeyam-cli/src/webserver/build/client/assets/files-DO4CZ16O.js +0 -1
  635. package/codeyam-cli/src/webserver/build/client/assets/git-CFCTYk9I.js +0 -15
  636. package/codeyam-cli/src/webserver/build/client/assets/globals-BZB_H1w2.css +0 -1
  637. package/codeyam-cli/src/webserver/build/client/assets/labs-Zk7ryIM1.js +0 -1
  638. package/codeyam-cli/src/webserver/build/client/assets/manifest-8daa4147.js +0 -1
  639. package/codeyam-cli/src/webserver/build/client/assets/memory-FweZHj5U.js +0 -93
  640. package/codeyam-cli/src/webserver/build/client/assets/root-DiRdBreB.js +0 -67
  641. package/codeyam-cli/src/webserver/build/client/assets/settings-DfuTtcJP.js +0 -1
  642. package/codeyam-cli/src/webserver/build/client/assets/simulations-B3aOzpCZ.js +0 -1
  643. package/codeyam-cli/src/webserver/build/client/assets/useCustomSizes-ByhSyh0W.js +0 -1
  644. package/codeyam-cli/src/webserver/build/client/assets/useLastLogLine-C14nCb1q.js +0 -2
  645. package/codeyam-cli/src/webserver/build/client/assets/useReportContext-O-jkvSPx.js +0 -1
  646. package/codeyam-cli/src/webserver/build/client/assets/useToast-9FIWuYfK.js +0 -1
  647. package/codeyam-cli/src/webserver/build/client/assets/xterm-DMSzMhqy.js +0 -9
  648. package/codeyam-cli/src/webserver/build/server/assets/index-BzAbACSx.js +0 -1
  649. package/codeyam-cli/src/webserver/build/server/assets/server-build-OdUocH6P.js +0 -362
  650. package/codeyam-cli/templates/codeyam-editor.md +0 -68
  651. package/scripts/finalize-analyzer.cjs +0 -13
  652. /package/codeyam-cli/templates/{codeyam-diagnose.md → commands/codeyam-diagnose.md} +0 -0
  653. /package/codeyam-cli/templates/{codeyam-debug.md → skills/codeyam-debug/SKILL.md} +0 -0
  654. /package/codeyam-cli/templates/{codeyam-new-rule.md → skills/codeyam-new-rule/SKILL.md} +0 -0
  655. /package/codeyam-cli/templates/{codeyam-setup.md → skills/codeyam-setup/SKILL.md} +0 -0
  656. /package/codeyam-cli/templates/{codeyam-sim.md → skills/codeyam-sim/SKILL.md} +0 -0
  657. /package/codeyam-cli/templates/{codeyam-test.md → skills/codeyam-test/SKILL.md} +0 -0
  658. /package/codeyam-cli/templates/{codeyam-verify.md → skills/codeyam-verify/SKILL.md} +0 -0
@@ -2,13 +2,109 @@ var _a, _b;
2
2
  import { WebSocketServer, WebSocket } from 'ws';
3
3
  import crypto from 'crypto';
4
4
  import fs from 'fs';
5
+ import os from 'os';
5
6
  import path from 'path';
6
7
  import * as pty from 'node-pty';
8
+ import { createMarkerTransformer } from "../utils/scenarioMarkers.js";
9
+ import { IdleDetector } from "./idleDetector.js";
10
+ import { mockStateEventEmitter } from "./mockStateEvents.js";
11
+ /**
12
+ * Strip the raw `claude ...` shell command from suppressed PTY output
13
+ * so it doesn't leak to the user in the fallback timeout path.
14
+ */
15
+ export function stripClaudeCommand(output) {
16
+ // Find the line containing the claude command and strip everything before
17
+ // and including it (shell prompt, ANSI codes, command echo). Preserve any
18
+ // real output that follows.
19
+ const idx = output.indexOf('claude ');
20
+ if (idx === -1)
21
+ return output;
22
+ // Find the end of the command line (\r or \n after "claude")
23
+ let end = idx;
24
+ while (end < output.length && output[end] !== '\r' && output[end] !== '\n') {
25
+ end++;
26
+ }
27
+ // Skip past trailing \r\n
28
+ while (end < output.length &&
29
+ (output[end] === '\r' || output[end] === '\n')) {
30
+ end++;
31
+ }
32
+ // Strip leading ANSI escape sequences from the remainder
33
+ // (e.g. bracketed paste mode toggles like \x1b[?2004l)
34
+ let rest = output.slice(end);
35
+ rest = rest.replace(/^(\x1b\[[\x20-\x3f]*[\x40-\x7e]|\x1b[()][A-Z0-9])*/, '');
36
+ return rest;
37
+ }
38
+ /**
39
+ * Detect whether a PTY output chunk contains Claude Code's welcome banner.
40
+ * Supports both the old box-drawing format (`╭─── Claude Code ───╮`)
41
+ * and the new block-art format (`▐▛███▜▌ Claude Code`).
42
+ */
43
+ export function isBannerChunk(data) {
44
+ // Strip ANSI escape sequences before checking — Claude Code's Ink renderer
45
+ // inserts SGR color codes between the banner characters (e.g. ▐\x1b[48;5;16m▛).
46
+ const plain = data.replace(/\x1b\[[0-9;?]*[A-Za-z]|\x1b\][^\x07]*\x07|\x1b[()][A-Z0-9]/g, '');
47
+ return plain.includes('╭') || plain.includes('▐▛');
48
+ }
49
+ /**
50
+ * Determine whether the startup output filter should be active.
51
+ * The filter strips the raw `claude --session-id ...` command from the
52
+ * terminal so the user never sees it.
53
+ */
54
+ export function shouldFilterStartup(opts) {
55
+ return opts.hasContext || opts.editorMode;
56
+ }
57
+ /**
58
+ * Manages PTY output suppression during Claude startup.
59
+ *
60
+ * Suppresses all output until the welcome banner arrives, then clears
61
+ * the screen. The claude command is stripped from any chunk that is forwarded
62
+ * (both the banner chunk on the normal path and the buffered output on the
63
+ * fallback timeout path).
64
+ */
65
+ export class StartupOutputFilter {
66
+ constructor() {
67
+ this.hasClearedScreen = false;
68
+ this.suppressedOutput = '';
69
+ }
70
+ /**
71
+ * Process a PTY data chunk. Returns an object describing what action to take:
72
+ * - `type: 'suppress'` — buffer the chunk, send nothing
73
+ * - `type: 'clear-and-send'` — clear screen, then send `data`
74
+ * - `type: 'send'` — send `data` as-is (post-startup)
75
+ */
76
+ processChunk(data) {
77
+ if (!this.hasClearedScreen && isBannerChunk(data)) {
78
+ this.hasClearedScreen = true;
79
+ const cleaned = stripClaudeCommand(data);
80
+ return { type: 'clear-and-send', data: cleaned };
81
+ }
82
+ if (!this.hasClearedScreen) {
83
+ this.suppressedOutput += data;
84
+ return { type: 'suppress' };
85
+ }
86
+ return { type: 'send', data };
87
+ }
88
+ /**
89
+ * Called when the fallback timeout fires (╭ never arrived).
90
+ * Returns the buffered output with the command stripped, or null if
91
+ * the screen was already cleared.
92
+ */
93
+ getTimeoutOutput() {
94
+ if (this.hasClearedScreen)
95
+ return null;
96
+ this.hasClearedScreen = true;
97
+ if (this.suppressedOutput.length === 0)
98
+ return null;
99
+ const cleaned = stripClaudeCommand(this.suppressedOutput);
100
+ return cleaned.length > 0 ? cleaned : null;
101
+ }
102
+ }
7
103
  // Use globalThis so the sessions Set is shared across module instances.
8
104
  // In Vite dev mode, this file is loaded twice: once by the Vite plugin (Node.js native)
9
105
  // and once by the SSR context (ssrLoadModule). Without globalThis, each instance
10
106
  // gets its own empty Set — so broadcastPreviewRefresh() called from the SSR instance
11
- // (via the /api/dev-mode-refresh endpoint) would broadcast to 0 sessions.
107
+ // (via the /api/dev-mode-preview endpoint) would broadcast to 0 sessions.
12
108
  const sessions = ((_a = globalThis).__codeyamTerminalSessions ?? (_a.__codeyamTerminalSessions = new Set()));
13
109
  // Detached PTYs waiting for reconnection (keyed by sessionId).
14
110
  // When a WebSocket drops, the PTY is moved here with a grace timer
@@ -17,104 +113,6 @@ const detachedPtys = ((_b = globalThis).__codeyamDetachedPtys ?? (_b.__codeyamDe
17
113
  const PING_INTERVAL_MS = 30000;
18
114
  const DETACH_GRACE_MS = 60000;
19
115
  const OUTPUT_BUFFER_MAX = 8 * 1024; // 8KB
20
- const ANSI_ESCAPE_RE = /\x1b\[[0-9;]*[a-zA-Z]/g;
21
- /**
22
- * Build a position map from ANSI-stripped indices to original indices.
23
- * posMap[strippedIndex] = originalIndex, skipping over ANSI sequences.
24
- */
25
- function buildAnsiPositionMap(data, stripped) {
26
- const posMap = [];
27
- for (let di = 0, si = 0; di < data.length; di++) {
28
- if (data[di] === '\x1b') {
29
- const seqMatch = data.slice(di).match(/^\x1b\[[0-9;]*[a-zA-Z]/);
30
- if (seqMatch) {
31
- di += seqMatch[0].length - 1; // -1 because loop increments
32
- continue;
33
- }
34
- }
35
- posMap[si] = di;
36
- si++;
37
- }
38
- posMap[stripped.length] = data.length; // sentinel for end-of-string markers
39
- return posMap;
40
- }
41
- /**
42
- * Transform {{scenario:Name:ID}} markers in PTY output into OSC 8 hyperlinks.
43
- * OSC 8 format: \x1b]8;;URL\x07VISIBLE_TEXT\x1b]8;;\x07
44
- * xterm.js renders the visible text as a clickable link.
45
- *
46
- * Claude Code's renderer inserts ANSI escape codes (colors/styles) within the
47
- * marker text, so we can't regex match on the raw PTY data directly. Instead,
48
- * strip ANSI codes to find markers, then map positions back to the original
49
- * string for replacement.
50
- */
51
- function transformScenarioMarkers(data, port) {
52
- // Strip ANSI escape sequences to get clean text for marker detection
53
- const stripped = data.replace(ANSI_ESCAPE_RE, '');
54
- if (!stripped.includes('{{scenario:'))
55
- return data;
56
- const posMap = buildAnsiPositionMap(data, stripped);
57
- // Find markers in the stripped text
58
- const markerRegex = /\{\{scenario:([^:}]+):([^}]+)\}\}/g;
59
- const replacements = [];
60
- let m;
61
- while ((m = markerRegex.exec(stripped)) !== null) {
62
- const url = `http://localhost:${port}/editor?scenario=${m[2]}&ref=link`;
63
- const visibleName = m[1];
64
- // Pad replacement to match the original marker's visible width so table
65
- // columns stay aligned after the shorter hyperlink text replaces the marker.
66
- const pad = ' '.repeat(Math.max(0, m[0].length - visibleName.length));
67
- replacements.push({
68
- origStart: posMap[m.index],
69
- origEnd: posMap[m.index + m[0].length],
70
- replacement: `\x1b]8;;${url}\x07${visibleName}\x1b]8;;\x07${pad}`,
71
- });
72
- }
73
- if (replacements.length === 0)
74
- return data;
75
- // Replace from end to start so earlier positions stay valid
76
- let result = data;
77
- for (let i = replacements.length - 1; i >= 0; i--) {
78
- const r = replacements[i];
79
- result =
80
- result.slice(0, r.origStart) + r.replacement + result.slice(r.origEnd);
81
- }
82
- return result;
83
- }
84
- /**
85
- * Create a stateful scenario marker transformer that buffers partial markers
86
- * across PTY chunks. Claude Code streams output token by token, so the PTY
87
- * can split a {{scenario:Name:ID}} marker across two (or more) data events.
88
- * Without buffering, split markers pass through un-transformed as raw text.
89
- */
90
- function createMarkerTransformer(port) {
91
- let buffer = '';
92
- return function transform(data) {
93
- // Prepend any buffered partial-marker text from the previous chunk
94
- const combined = buffer + data;
95
- buffer = '';
96
- // Strip ANSI to detect partial markers at the end
97
- const stripped = combined.replace(ANSI_ESCAPE_RE, '');
98
- // Check for an unclosed {{ at the end — potential partial marker
99
- const lastOpen = stripped.lastIndexOf('{{');
100
- if (lastOpen !== -1 && !stripped.slice(lastOpen).includes('}}')) {
101
- // Map the stripped position back to the original string
102
- const posMap = buildAnsiPositionMap(combined, stripped);
103
- const splitPos = posMap[lastOpen];
104
- // Safety: if partial marker exceeds 500 chars, it's not a real marker — flush it
105
- if (combined.length - splitPos > 500) {
106
- return transformScenarioMarkers(combined, port);
107
- }
108
- buffer = combined.slice(splitPos);
109
- const toSend = combined.slice(0, splitPos);
110
- // If nothing to send yet (entire chunk is a partial marker), return empty
111
- if (toSend.length === 0)
112
- return '';
113
- return transformScenarioMarkers(toSend, port);
114
- }
115
- return transformScenarioMarkers(combined, port);
116
- };
117
- }
118
116
  // Ping interval reference — shared so cleanup can clear it
119
117
  let pingInterval = globalThis.__codeyamPingInterval ?? null;
120
118
  // Keys to forward from the server env into the PTY shell.
@@ -149,9 +147,22 @@ const ENV_PASSTHROUGH_KEYS = [
149
147
  'HOMEBREW_CELLAR',
150
148
  'HOMEBREW_REPOSITORY',
151
149
  ];
152
- function buildPtyEnv() {
150
+ // Additional env vars needed on Windows
151
+ const WINDOWS_ENV_PASSTHROUGH_KEYS = [
152
+ 'USERPROFILE',
153
+ 'APPDATA',
154
+ 'LOCALAPPDATA',
155
+ 'COMSPEC',
156
+ 'SystemRoot',
157
+ 'TEMP',
158
+ 'TMP',
159
+ ];
160
+ export function buildPtyEnv(options) {
153
161
  const env = {};
154
- for (const key of ENV_PASSTHROUGH_KEYS) {
162
+ const keys = process.platform === 'win32'
163
+ ? [...ENV_PASSTHROUGH_KEYS, ...WINDOWS_ENV_PASSTHROUGH_KEYS]
164
+ : ENV_PASSTHROUGH_KEYS;
165
+ for (const key of keys) {
155
166
  const val = process.env[key];
156
167
  if (val != null)
157
168
  env[key] = val;
@@ -159,8 +170,45 @@ function buildPtyEnv() {
159
170
  // Always set TERM for proper terminal behavior
160
171
  if (!env.TERM)
161
172
  env.TERM = 'xterm-256color';
173
+ // Signal to hooks that this is an editor Build session.
174
+ // Without this, editor hooks fire in ALL Claude sessions in the project.
175
+ if (options?.editorMode) {
176
+ env.CODEYAM_EDITOR_ACTIVE = '1';
177
+ }
162
178
  return env;
163
179
  }
180
+ /**
181
+ * Returns the shell executable and arguments for PTY spawning,
182
+ * handling platform differences (Windows uses PowerShell, Unix uses $SHELL).
183
+ */
184
+ export function getShellConfig() {
185
+ if (process.platform === 'win32') {
186
+ return {
187
+ shell: 'powershell.exe',
188
+ args: ['-ExecutionPolicy', 'Bypass', '-NoLogo'],
189
+ };
190
+ }
191
+ const defaultShell = process.platform === 'darwin' ? '/bin/zsh' : '/bin/sh';
192
+ return {
193
+ shell: process.env.SHELL || defaultShell,
194
+ args: ['-l'],
195
+ };
196
+ }
197
+ /**
198
+ * Returns a safe working directory for the PTY, falling back through
199
+ * CODEYAM_ROOT_PATH → cwd → HOME/USERPROFILE → os.tmpdir().
200
+ */
201
+ export function getSafeCwd() {
202
+ const cwd = process.env.CODEYAM_ROOT_PATH || process.cwd();
203
+ if (fs.existsSync(cwd))
204
+ return cwd;
205
+ const home = process.platform === 'win32'
206
+ ? process.env.USERPROFILE || process.env.HOME
207
+ : process.env.HOME;
208
+ if (home && fs.existsSync(home))
209
+ return home;
210
+ return os.tmpdir();
211
+ }
164
212
  /**
165
213
  * Convert a name to a safe file name matching CodeYam's convention.
166
214
  * e.g. "Default Scenario" -> "Default_Scenario"
@@ -287,7 +335,7 @@ function writeDevModeContext(ctx) {
287
335
  // Server
288
336
  const serverPort = process.env.CODEYAM_PORT || '3111';
289
337
  lines.push('## Server');
290
- lines.push(`- **Refresh preview:** \`curl -X POST http://localhost:${serverPort}/api/dev-mode-refresh\``);
338
+ lines.push(`- **Refresh preview:** \`curl -X POST http://localhost:${serverPort}/api/dev-mode-preview -H 'Content-Type: application/json' -d '{"dimension":"Desktop"}'\` (dimension is REQUIRED)`);
291
339
  lines.push('');
292
340
  fs.writeFileSync(contextPath, lines.join('\n'), 'utf8');
293
341
  return true;
@@ -324,28 +372,34 @@ function writeEditorModeContext(ctx) {
324
372
  `- **Proxy:** http://localhost:${proxyPort} (used by the browser iframe only — do NOT use for health checks)`,
325
373
  '',
326
374
  '## Workflow',
327
- '- **Guided steps:** Run `codeyam editor` for the next step (plan → prototype → confirm → deconstruct → extract → glossary → analyze → app scenarios → user scenarios → verify → review)',
328
- '- Each feature follows 11 steps: `codeyam editor 1` through `codeyam editor 11`',
329
- '- Steps 1, 3, and 11 require user confirmation before proceeding',
375
+ '- **Guided steps:** Run `codeyam editor steps` for the next step (plan → prepare → prototype → verify prototype → confirm → deconstruct → extract → glossary → analyze → app scenarios → user scenarios → verify → journal → review → present → commit → finalize → push)',
376
+ '- Each feature follows 18 steps — run `codeyam editor steps` to see what to do next. Never expose `codeyam editor` commands to the user.',
377
+ '- **Run ONE step at a time.** Read the FULL output, complete every checklist item, then advance. NEVER batch-run steps in a loop or delegate them to a subagent.',
378
+ '- Steps 1, 5, 15, and 18 require user confirmation before proceeding',
379
+ '',
380
+ '## Preview Updates',
381
+ '- **Refresh the preview frequently** — the user watches the preview as you work. Refresh after every meaningful change (new page, UI section, data seeding, styling), not just at the end.',
382
+ `- **Refresh command:** \`curl -s -X POST http://localhost:${serverPort}/api/dev-mode-preview -H 'Content-Type: application/json' -d '{"dimension":"Desktop"}'\` (dimension is REQUIRED)`,
383
+ '- Aim for 4-8+ preview updates during a typical building session.',
330
384
  '',
331
385
  '## Verifying the Dev Server',
332
386
  '- Get the dev server URL: `curl -s http://localhost:' +
333
387
  serverPort +
334
388
  '/api/editor-dev-server` → look at the `"url"` field (e.g., `http://localhost:3000`)',
335
- '- Check the page loads: `curl -s -o /dev/null -w "%{http_code}" http://localhost:3000` (use the actual dev server URL, NOT the proxy)',
336
- '- Check API routes work: `curl -s http://localhost:3000/api/your-route` (should return JSON, not "Internal Server Error")',
389
+ '- Verify pages and API routes: `codeyam editor verify-routes \'{"paths":["/"],"apiRoutes":["/api/your-route"]}\'` (checks HTTP status and JSON validity)',
337
390
  '- **NEVER check localhost:' +
338
391
  proxyPort +
339
392
  ' for health** — the proxy returns 200 even when the app is broken',
340
393
  '',
341
394
  '## API Endpoints',
342
- `- **Register scenario (auto-captures screenshot):** \`codeyam editor register '{"name":"...","description":"...","mockData":{"routes":{"/api/tasks":{"body":[...]}}}}'\``,
395
+ `- **Register scenario (auto-captures screenshot):** \`codeyam editor register '{"name":"...","url":"/page-to-screenshot","type":"application","seed":{...}}'\` — ALWAYS include "url" for the page to screenshot. For large payloads, write JSON to a file and use @ prefix: \`codeyam editor register @/tmp/scenario.json\``,
343
396
  `- **Get active scenario data:** \`curl http://localhost:${serverPort}/api/editor-scenario-data\``,
344
- `- **Refresh preview:** \`curl -X POST http://localhost:${serverPort}/api/dev-mode-refresh\``,
397
+ `- **Refresh/navigate/switch preview:** \`curl -X POST http://localhost:${serverPort}/api/dev-mode-preview -H 'Content-Type: application/json' -d '{"dimension":"Desktop"}'\` (dimension is REQUIRED in every call; add \`"path":"/route"\` to navigate; add \`"scenarioId":"..."\` to switch scenario). Clears logs, waits for HMR, checks SSR health.`,
345
398
  `- **Refresh config:** \`curl -X POST http://localhost:${serverPort}/api/editor-refresh\` (also starts dev server if a webapp is detected)`,
346
399
  `- **Dev server status:** \`curl http://localhost:${serverPort}/api/editor-dev-server\``,
347
400
  `- **Start dev server:** \`curl -X POST http://localhost:${serverPort}/api/editor-dev-server -H 'Content-Type: application/json' -d '{"action":"start"}'\``,
348
401
  `- **Restart dev server:** \`curl -X POST http://localhost:${serverPort}/api/editor-dev-server -H 'Content-Type: application/json' -d '{"action":"restart"}'\``,
402
+ `- **Feature complete (after push):** \`curl -s -X POST http://localhost:${serverPort}/api/editor-feature-complete\` — signals the UI that the feature is done. Call this after step 18 push/skip, then STOP.`,
349
403
  `- **Re-capture scenario screenshot:** \`curl -X POST http://localhost:${serverPort}/api/editor-capture-scenario -H 'Content-Type: application/json' -d '{"scenarioId":"...","url":"..."}'\` (for manual re-capture; register auto-captures)`,
350
404
  `- **Journal screenshot:** \`curl -X POST http://localhost:${serverPort}/api/editor-journal-screenshot -H 'Content-Type: application/json' -d '{"url":"...","filename":"..."}'\``,
351
405
  `- **Journal entry:** \`curl -X POST http://localhost:${serverPort}/api/editor-journal-entry -H 'Content-Type: application/json' -d '{"title":"...","type":"feature","description":"..."}'\``,
@@ -358,17 +412,21 @@ function writeEditorModeContext(ctx) {
358
412
  '- POST/PUT/DELETE always go through to the real dev server',
359
413
  '',
360
414
  '## Component Isolation Routes',
361
- '- To screenshot individual components, create ONE isolation route per component:',
362
- ' - **Remix:** `app/routes/codeyam-isolate.ComponentName.tsx` → `/codeyam-isolate/ComponentName`',
363
- ' - **Next.js:** `app/codeyam-isolate/ComponentName/page.tsx` `/codeyam-isolate/ComponentName`',
415
+ '- Create isolation route dirs: `codeyam editor isolate ComponentA ComponentB ...`',
416
+ ' - This creates the layout guard and a directory per component under `app/isolated-components/`',
417
+ '- Create ONE isolation route page per component:',
418
+ ' - **Remix:** `app/routes/isolated-components.ComponentName.tsx` → `/isolated-components/ComponentName`',
419
+ ' - **Next.js:** `app/isolated-components/ComponentName/page.tsx` → `/isolated-components/ComponentName`',
420
+ ' - **Expo:** `app/isolated-components/ComponentName.tsx` → `/isolated-components/ComponentName` (use `useLocalSearchParams` from expo-router)',
364
421
  '- The route defines a `scenarios` object mapping scenario names to props, reads `?s=ScenarioName` from the URL, and renders the component',
365
- '- Wrap the component in a centered container: `<div style="display:flex;justify-content:center;align-items:center;min-height:100vh;padding:20px"><div style="width:100%;max-width:...">` — set max-width to match the component\'s real container (e.g. card in 3-col grid → 24rem)',
422
+ '- For web apps: Wrap the component in a centered container: `<div style="display:flex;justify-content:center;align-items:center;min-height:100vh"><div style="width:100%;max-width:...">` — set max-width to match the component\'s real container (e.g. card in 3-col grid → 24rem)',
423
+ '- For Expo: Wrap with `<View nativeID="codeyam-capture">` (nativeID maps to id on web for screenshot capture)',
366
424
  '- **Create multiple scenarios per component** (like tests): default/happy path, edge cases (empty data, long text, max items), different visual states (loading, error, disabled)',
367
- '- Register each scenario: `codeyam editor register \'{"name":"ComponentName - Scenario","componentName":"ComponentName","componentPath":"path/to/file.tsx","url":"/codeyam-isolate/ComponentName?s=Scenario","mockData":{"routes":{"/api/...":{"body":[...]}}}}\'`',
425
+ '- Register each scenario: `codeyam editor register \'{"name":"ComponentName - Scenario","componentName":"ComponentName","componentPath":"path/to/file.tsx","url":"/isolated-components/ComponentName?s=Scenario","mockData":{"routes":{"/api/...":{"body":[...]}}}}\'`',
368
426
  '- The url is a PATH, not a full URL — the proxy appends it and intercepts API calls the component makes',
369
427
  '- `mockData.routes` provides data for any API calls the component makes internally (omit if none)',
370
428
  '- Isolation routes stay in the project so the editor preview can display them',
371
- '- Ensure `.gitignore` includes `**/codeyam-isolate*` so they are not committed',
429
+ '- Ensure `.gitignore` includes `**/isolated-components*` so they are not committed',
372
430
  '',
373
431
  '## Files',
374
432
  '- **Scenario data:** .codeyam/editor-scenarios/{scenario-id}.json',
@@ -382,9 +440,21 @@ function writeEditorModeContext(ctx) {
382
440
  const hasPackageJson = fs.existsSync(path.join(codeyamRoot, 'package.json'));
383
441
  if (!hasPackageJson) {
384
442
  lines.push('## Status');
385
- lines.push('- **Empty project** — no package.json found. Ask the user what they want to build.');
443
+ lines.push('- **Empty project** — no package.json found. Run `codeyam editor steps` to begin.');
386
444
  lines.push('');
387
445
  }
446
+ // Include handoff context if a provider switch generated one
447
+ try {
448
+ const handoffContextPath = path.join(codeyamRoot, '.codeyam', 'handoff-context.md');
449
+ if (fs.existsSync(handoffContextPath)) {
450
+ lines.push('');
451
+ lines.push(fs.readFileSync(handoffContextPath, 'utf8'));
452
+ lines.push('');
453
+ }
454
+ }
455
+ catch {
456
+ // Non-fatal
457
+ }
388
458
  fs.writeFileSync(contextPath, lines.join('\n'), 'utf8');
389
459
  return true;
390
460
  }
@@ -422,6 +492,12 @@ export function attachTerminalServer(httpServer) {
422
492
  }
423
493
  }, PING_INTERVAL_MS);
424
494
  globalThis.__codeyamPingInterval = pingInterval;
495
+ // Subscribe to mock state events and broadcast to all terminal clients
496
+ mockStateEventEmitter.on('event', (event) => {
497
+ if (event.type === 'data-mutation-forwarded') {
498
+ broadcastDataMutationForwarded(event.method, event.pathname);
499
+ }
500
+ });
425
501
  wss.on('connection', (ws, req) => {
426
502
  // Parse entity context from query params
427
503
  const url = new URL(req.url || '', `http://${req.headers.host}`);
@@ -435,6 +511,9 @@ export function attachTerminalServer(httpServer) {
435
511
  const projectSlug = url.searchParams.get('projectSlug') || '';
436
512
  const editorMode = url.searchParams.get('editorMode') === 'true';
437
513
  const reconnectId = url.searchParams.get('reconnectId') || '';
514
+ const claudeStartMode = url.searchParams.get('claudeStartMode') || '';
515
+ const claudeSessionId = url.searchParams.get('claudeSessionId') || '';
516
+ const editorStepLabel = url.searchParams.get('editorStepLabel') || '';
438
517
  // --- Reconnection: reattach to a detached PTY ---
439
518
  if (reconnectId && detachedPtys.has(reconnectId)) {
440
519
  const detached = detachedPtys.get(reconnectId);
@@ -461,13 +540,27 @@ export function attachTerminalServer(httpServer) {
461
540
  let detachedFlag = false;
462
541
  const reconnectPort = process.env.CODEYAM_PORT || '3111';
463
542
  const reconnectTransformMarkers = createMarkerTransformer(reconnectPort);
543
+ const reconnectIdleDetector = new IdleDetector({
544
+ onIdle: () => {
545
+ if (ws.readyState === WebSocket.OPEN) {
546
+ console.log('[terminalServer] Sending claude-idle (reconnected)');
547
+ ws.send(JSON.stringify({ type: 'claude-idle' }));
548
+ }
549
+ },
550
+ onActive: () => {
551
+ if (ws.readyState === WebSocket.OPEN) {
552
+ console.log('[terminalServer] Sending claude-active (reconnected)');
553
+ ws.send(JSON.stringify({ type: 'claude-active' }));
554
+ }
555
+ },
556
+ }, { activeOutputPattern: /[✶✢·◼]/ });
464
557
  detached.ptyProcess.onData((data) => {
465
558
  if (detachedFlag)
466
559
  return; // Superseded by a newer listener
467
560
  if (ws.readyState === WebSocket.OPEN) {
468
561
  if (!detached.hasClearedScreen &&
469
562
  detached.hasContext &&
470
- data.includes('╭')) {
563
+ isBannerChunk(data)) {
471
564
  detached.hasClearedScreen = true;
472
565
  ws.send(JSON.stringify({ type: 'output', data: '\x1b[2J\x1b[H' }));
473
566
  }
@@ -475,14 +568,12 @@ export function attachTerminalServer(httpServer) {
475
568
  if (transformed.length > 0) {
476
569
  ws.send(JSON.stringify({ type: 'output', data: transformed }));
477
570
  }
478
- const stripped = data.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, '');
479
- if (stripped.includes('Editor Mode \u2014')) {
480
- console.log('[terminalServer] Detected claude-idle signal (reconnect)');
481
- ws.send(JSON.stringify({ type: 'claude-idle' }));
482
- }
571
+ reconnectIdleDetector.onPtyOutput(data);
483
572
  }
484
573
  });
485
574
  detached.ptyProcess.onExit(() => {
575
+ console.log('[terminalServer] PTY exited (reconnected), flushing idle state');
576
+ reconnectIdleDetector.disposeAndFlush();
486
577
  sessions.delete(session);
487
578
  if (ws.readyState === WebSocket.OPEN) {
488
579
  ws.close();
@@ -493,6 +584,7 @@ export function attachTerminalServer(httpServer) {
493
584
  try {
494
585
  const msg = JSON.parse(raw.toString());
495
586
  if (msg.type === 'input') {
587
+ reconnectIdleDetector.onUserInput();
496
588
  detached.ptyProcess.write(msg.data);
497
589
  }
498
590
  else if (msg.type === 'resize' && msg.cols && msg.rows) {
@@ -513,19 +605,17 @@ export function attachTerminalServer(httpServer) {
513
605
  return;
514
606
  }
515
607
  // --- New connection: spawn a fresh PTY ---
516
- const shell = process.env.SHELL || '/bin/zsh';
517
- const cwd = process.env.CODEYAM_ROOT_PATH || process.cwd();
518
- // Verify cwd exists, fall back to HOME
519
- const safeCwd = fs.existsSync(cwd) ? cwd : process.env.HOME || '/tmp';
608
+ const { shell, args: shellArgs } = getShellConfig();
609
+ const safeCwd = getSafeCwd();
520
610
  // Spawn PTY with a clean env (no giant JSON blobs from CODEYAM_PROJECT etc.)
521
611
  let ptyProcess;
522
612
  try {
523
- ptyProcess = pty.spawn(shell, ['-l'], {
613
+ ptyProcess = pty.spawn(shell, shellArgs, {
524
614
  name: 'xterm-256color',
525
615
  cols: 120,
526
616
  rows: 30,
527
617
  cwd: safeCwd,
528
- env: buildPtyEnv(),
618
+ env: buildPtyEnv({ editorMode }),
529
619
  });
530
620
  }
531
621
  catch (error) {
@@ -565,9 +655,41 @@ export function attachTerminalServer(httpServer) {
565
655
  projectSlug,
566
656
  });
567
657
  let hasClearedScreen = false;
568
- // Rolling buffer of trailing text to detect "Editor Mode —" across PTY chunks.
569
- let idleDetectBuffer = '';
570
- const IDLE_MARKER = 'Editor Mode \u2014';
658
+ const filterStartup = shouldFilterStartup({ hasContext, editorMode });
659
+ const startupFilter = filterStartup ? new StartupOutputFilter() : null;
660
+ // Safety timeout: stop suppressing output after 5s even if ╭ never arrives.
661
+ // Prevents "Starting Claude..." hanging forever if the banner format changes.
662
+ if (filterStartup) {
663
+ setTimeout(() => {
664
+ const output = startupFilter.getTimeoutOutput();
665
+ if (output !== null) {
666
+ hasClearedScreen = true;
667
+ console.log('[terminalServer] Suppression timeout — showing output');
668
+ if (ws.readyState === WebSocket.OPEN) {
669
+ // Clear the "Starting Claude..." message
670
+ ws.send(JSON.stringify({ type: 'output', data: '\x1b[2J\x1b[H' }));
671
+ const transformed = transformMarkers(output);
672
+ if (transformed.length > 0) {
673
+ ws.send(JSON.stringify({ type: 'output', data: transformed }));
674
+ }
675
+ }
676
+ }
677
+ }, 5000);
678
+ }
679
+ const idleDetector = new IdleDetector({
680
+ onIdle: () => {
681
+ if (ws.readyState === WebSocket.OPEN) {
682
+ console.log('[terminalServer] Sending claude-idle');
683
+ ws.send(JSON.stringify({ type: 'claude-idle' }));
684
+ }
685
+ },
686
+ onActive: () => {
687
+ if (ws.readyState === WebSocket.OPEN) {
688
+ console.log('[terminalServer] Sending claude-active');
689
+ ws.send(JSON.stringify({ type: 'claude-active' }));
690
+ }
691
+ },
692
+ }, { activeOutputPattern: /[✶✢·◼]/ });
571
693
  // PTY output -> WebSocket
572
694
  const serverPort = process.env.CODEYAM_PORT || '3111';
573
695
  // Stateful transformer that buffers partial {{scenario:...}} markers
@@ -575,35 +697,37 @@ export function attachTerminalServer(httpServer) {
575
697
  const transformMarkers = createMarkerTransformer(serverPort);
576
698
  ptyProcess.onData((data) => {
577
699
  if (ws.readyState === WebSocket.OPEN) {
578
- // When Claude Code starts (indicated by its box-drawing welcome banner),
579
- // clear the screen to hide the raw shell command.
580
- if (!hasClearedScreen && hasContext && data.includes('╭')) {
581
- hasClearedScreen = true;
582
- ws.send(JSON.stringify({ type: 'output', data: '\x1b[2J\x1b[H' }));
583
- }
584
- // Transform {{scenario:Name:ID}} markers into OSC 8 clickable hyperlinks.
585
- // Uses stateful buffering to handle markers split across PTY chunks.
586
- const transformed = transformMarkers(data);
587
- if (transformed.length > 0) {
588
- ws.send(JSON.stringify({ type: 'output', data: transformed }));
589
- }
590
- // Detect the Stop hook output — signals Claude is waiting for user input.
591
- // The hook outputs "Editor Mode —" when Claude finishes a turn.
592
- // Strip ANSI escape codes and check buffer+current to handle cross-chunk splits.
593
- const stripped = data.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, '');
594
- const combined = idleDetectBuffer + stripped;
595
- if (combined.includes(IDLE_MARKER)) {
596
- console.log('[terminalServer] Detected claude-idle signal');
597
- ws.send(JSON.stringify({ type: 'claude-idle' }));
598
- idleDetectBuffer = '';
700
+ // During startup, suppress output until Claude's welcome banner (╭)
701
+ // arrives, then clear screen and strip the raw command from the chunk.
702
+ if (startupFilter && !hasClearedScreen) {
703
+ const result = startupFilter.processChunk(data);
704
+ if (result.type === 'clear-and-send') {
705
+ hasClearedScreen = true;
706
+ ws.send(JSON.stringify({ type: 'output', data: '\x1b[2J\x1b[H' }));
707
+ if (result.data.length > 0) {
708
+ const transformed = transformMarkers(result.data);
709
+ if (transformed.length > 0) {
710
+ ws.send(JSON.stringify({ type: 'output', data: transformed }));
711
+ }
712
+ }
713
+ idleDetector.onPtyOutput(data);
714
+ }
715
+ // type === 'suppress': skip sending and idle detection
599
716
  }
600
717
  else {
601
- // Keep trailing chars in case the marker spans two chunks
602
- idleDetectBuffer = stripped.slice(-(IDLE_MARKER.length - 1));
718
+ // Transform {{scenario:Name:ID}} markers into OSC 8 clickable hyperlinks.
719
+ // Uses stateful buffering to handle markers split across PTY chunks.
720
+ const transformed = transformMarkers(data);
721
+ if (transformed.length > 0) {
722
+ ws.send(JSON.stringify({ type: 'output', data: transformed }));
723
+ }
724
+ idleDetector.onPtyOutput(data);
603
725
  }
604
726
  }
605
727
  });
606
728
  ptyProcess.onExit(() => {
729
+ console.log('[terminalServer] PTY exited, flushing idle state');
730
+ idleDetector.disposeAndFlush();
607
731
  sessions.delete(session);
608
732
  // Also clean up from detachedPtys if it was detached
609
733
  if (detachedPtys.has(sessionId)) {
@@ -619,6 +743,7 @@ export function attachTerminalServer(httpServer) {
619
743
  try {
620
744
  const msg = JSON.parse(raw.toString());
621
745
  if (msg.type === 'input') {
746
+ idleDetector.onUserInput();
622
747
  ptyProcess.write(msg.data);
623
748
  }
624
749
  else if (msg.type === 'resize' && msg.cols && msg.rows) {
@@ -636,11 +761,54 @@ export function attachTerminalServer(httpServer) {
636
761
  ws.on('close', () => {
637
762
  detachSession(session, hasContext, hasClearedScreen);
638
763
  });
764
+ // Show a loading indicator while Claude Code starts up.
765
+ // PTY output is suppressed until Claude's welcome banner (╭) appears
766
+ // and triggers a screen clear, so the user never sees the raw command.
767
+ if (filterStartup) {
768
+ ws.send(JSON.stringify({
769
+ type: 'output',
770
+ data: '\x1b[2J\x1b[H\r\n\x1b[90m Starting Claude...\x1b[0m\r\n',
771
+ }));
772
+ }
639
773
  // Start Claude Code with the appropriate skill.
640
774
  // Using a skill avoids shell escaping issues and multi-line paste detection.
775
+ //
776
+ // Session recovery modes (editor only):
777
+ // resume + sessionId → claude --resume <uuid> (resumes exact conversation)
778
+ // resume, no sessionId → claude --continue (fallback for pre-existing sessions)
779
+ // fresh → generate UUID, write to .codeyam/claude-session-id.txt,
780
+ // launch claude --session-id <uuid> '/codeyam-editor'
781
+ //
782
+ // The UUID is generated HERE (not in printStep1) so it's available before
783
+ // Claude launches. printStep1 runs inside the session — too late.
641
784
  setTimeout(() => {
642
785
  if (editorMode && hasContext) {
643
- ptyProcess.write("claude '/codeyam-editor'\r");
786
+ if (claudeStartMode === 'resume' && claudeSessionId) {
787
+ const resumePrompt = editorStepLabel === 'Present'
788
+ ? 'The session was interrupted. Please rerun show-results.'
789
+ : 'The session was interrupted. Please continue where you left off.';
790
+ ptyProcess.write(`claude --resume '${claudeSessionId}' '${resumePrompt}'\r`);
791
+ }
792
+ else if (claudeStartMode === 'resume') {
793
+ // No session ID available — fall back to most recent session
794
+ const resumePrompt = editorStepLabel === 'Present'
795
+ ? 'The session was interrupted. Please rerun show-results.'
796
+ : 'The session was interrupted. Please continue where you left off.';
797
+ ptyProcess.write(`claude --continue '${resumePrompt}'\r`);
798
+ }
799
+ else {
800
+ // Fresh session: generate a trackable UUID
801
+ const newSessionId = crypto.randomUUID();
802
+ const sessionIdPath = path.join(safeCwd, '.codeyam', 'claude-session-id.txt');
803
+ try {
804
+ fs.mkdirSync(path.dirname(sessionIdPath), { recursive: true });
805
+ fs.writeFileSync(sessionIdPath, newSessionId, 'utf8');
806
+ }
807
+ catch (err) {
808
+ console.error('[terminalServer] Failed to write claude-session-id.txt:', err);
809
+ }
810
+ ptyProcess.write(`claude --session-id '${newSessionId}' '/codeyam-editor'\r`);
811
+ }
644
812
  }
645
813
  else if (hasContext) {
646
814
  ptyProcess.write("claude '/codeyam-dev-mode'\r");
@@ -696,8 +864,116 @@ function detachSession(session, hasContext = false, hasClearedScreen = false) {
696
864
  * Send a refresh-preview message to all connected terminal WebSocket clients.
697
865
  * The Terminal component relays this to the parent page to reload the iframe.
698
866
  */
699
- export function broadcastPreviewRefresh() {
700
- const msg = JSON.stringify({ type: 'refresh-preview' });
867
+ export function broadcastPreviewRefresh(path, scenarioId) {
868
+ const msg = JSON.stringify({
869
+ type: 'refresh-preview',
870
+ ...(path && { path }),
871
+ ...(scenarioId && { scenarioId }),
872
+ });
873
+ let count = 0;
874
+ for (const session of sessions) {
875
+ try {
876
+ if (session.ws.readyState === WebSocket.OPEN) {
877
+ session.ws.send(msg);
878
+ count++;
879
+ }
880
+ }
881
+ catch {
882
+ // Ignore send errors
883
+ }
884
+ }
885
+ return count;
886
+ }
887
+ /**
888
+ * Notify all connected terminal WebSocket clients that a data mutation
889
+ * was forwarded to the real dev server (seed-based scenario).
890
+ * The Terminal component relays this to editor.tsx to show a save banner.
891
+ */
892
+ export function broadcastDataMutationForwarded(method, pathname) {
893
+ const msg = JSON.stringify({
894
+ type: 'data-mutation-forwarded',
895
+ method,
896
+ pathname,
897
+ });
898
+ let count = 0;
899
+ for (const session of sessions) {
900
+ try {
901
+ if (session.ws.readyState === WebSocket.OPEN) {
902
+ session.ws.send(msg);
903
+ count++;
904
+ }
905
+ }
906
+ catch {
907
+ // Ignore send errors
908
+ }
909
+ }
910
+ return count;
911
+ }
912
+ /**
913
+ * Show the results panel below the terminal in the Build tab.
914
+ * Triggered by Claude at end of step 12.
915
+ */
916
+ export function broadcastShowResults() {
917
+ const msg = JSON.stringify({ type: 'show-results' });
918
+ let count = 0;
919
+ for (const session of sessions) {
920
+ try {
921
+ if (session.ws.readyState === WebSocket.OPEN) {
922
+ session.ws.send(msg);
923
+ count++;
924
+ }
925
+ }
926
+ catch {
927
+ // Ignore send errors
928
+ }
929
+ }
930
+ return count;
931
+ }
932
+ /**
933
+ * Hide the results panel (e.g. after Save & Commit).
934
+ */
935
+ export function broadcastHideResults() {
936
+ const msg = JSON.stringify({ type: 'hide-results' });
937
+ let count = 0;
938
+ for (const session of sessions) {
939
+ try {
940
+ if (session.ws.readyState === WebSocket.OPEN) {
941
+ session.ws.send(msg);
942
+ count++;
943
+ }
944
+ }
945
+ catch {
946
+ // Ignore send errors
947
+ }
948
+ }
949
+ return count;
950
+ }
951
+ /**
952
+ * Notify the editor UI that the current feature is complete (after push/skip).
953
+ * The UI shows a transition overlay letting the user start fresh or continue.
954
+ */
955
+ export function broadcastFeatureComplete() {
956
+ const msg = JSON.stringify({ type: 'feature-complete' });
957
+ let count = 0;
958
+ for (const session of sessions) {
959
+ try {
960
+ if (session.ws.readyState === WebSocket.OPEN) {
961
+ session.ws.send(msg);
962
+ count++;
963
+ }
964
+ }
965
+ catch {
966
+ // Ignore send errors
967
+ }
968
+ }
969
+ return count;
970
+ }
971
+ /**
972
+ * Send a set-viewport message to all connected terminal WebSocket clients.
973
+ * The Terminal component relays this to the parent page to update the preview viewport.
974
+ */
975
+ export function broadcastSetViewport(viewport) {
976
+ const msg = JSON.stringify({ type: 'set-viewport', ...viewport });
701
977
  let count = 0;
702
978
  for (const session of sessions) {
703
979
  try {