@qotaq/lalphgram 0.1.0

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 (517) hide show
  1. package/Events/package.json +6 -0
  2. package/LICENSE +21 -0
  3. package/Main/package.json +6 -0
  4. package/README.md +1 -0
  5. package/dist/cjs/Events.js +55 -0
  6. package/dist/cjs/Events.js.map +1 -0
  7. package/dist/cjs/LalphMain.js +59 -0
  8. package/dist/cjs/LalphMain.js.map +1 -0
  9. package/dist/cjs/Main.js +115 -0
  10. package/dist/cjs/Main.js.map +1 -0
  11. package/dist/cjs/index.js +281 -0
  12. package/dist/cjs/index.js.map +1 -0
  13. package/dist/cjs/lib/AnalysisPrompts.js +61 -0
  14. package/dist/cjs/lib/AnalysisPrompts.js.map +1 -0
  15. package/dist/cjs/lib/BranchParser.js +45 -0
  16. package/dist/cjs/lib/BranchParser.js.map +1 -0
  17. package/dist/cjs/lib/MermaidToPlantUml.js +96 -0
  18. package/dist/cjs/lib/MermaidToPlantUml.js.map +1 -0
  19. package/dist/cjs/lib/SpecHtmlGenerator.js +160 -0
  20. package/dist/cjs/lib/SpecHtmlGenerator.js.map +1 -0
  21. package/dist/cjs/lib/StreamJsonParser.js +88 -0
  22. package/dist/cjs/lib/StreamJsonParser.js.map +1 -0
  23. package/dist/cjs/lib/TelegramFormatter.js +122 -0
  24. package/dist/cjs/lib/TelegramFormatter.js.map +1 -0
  25. package/dist/cjs/lib/TelegraphHtml.js +65 -0
  26. package/dist/cjs/lib/TelegraphHtml.js.map +1 -0
  27. package/dist/cjs/lib/TelegraphMarkdown.js +346 -0
  28. package/dist/cjs/lib/TelegraphMarkdown.js.map +1 -0
  29. package/dist/cjs/schemas/CredentialSchemas.js +31 -0
  30. package/dist/cjs/schemas/CredentialSchemas.js.map +1 -0
  31. package/dist/cjs/schemas/GitHubSchemas.js +60 -0
  32. package/dist/cjs/schemas/GitHubSchemas.js.map +1 -0
  33. package/dist/cjs/schemas/LinearSchemas.js +63 -0
  34. package/dist/cjs/schemas/LinearSchemas.js.map +1 -0
  35. package/dist/cjs/schemas/ProjectSchemas.js +26 -0
  36. package/dist/cjs/schemas/ProjectSchemas.js.map +1 -0
  37. package/dist/cjs/schemas/TrackerSchemas.js +35 -0
  38. package/dist/cjs/schemas/TrackerSchemas.js.map +1 -0
  39. package/dist/cjs/services/AppContext.js +57 -0
  40. package/dist/cjs/services/AppContext.js.map +1 -0
  41. package/dist/cjs/services/AppRuntimeConfig.js +35 -0
  42. package/dist/cjs/services/AppRuntimeConfig.js.map +1 -0
  43. package/dist/cjs/services/AutoMerge.js +140 -0
  44. package/dist/cjs/services/AutoMerge.js.map +1 -0
  45. package/dist/cjs/services/ChatMachine.js +873 -0
  46. package/dist/cjs/services/ChatMachine.js.map +1 -0
  47. package/dist/cjs/services/CommentTimer.js +81 -0
  48. package/dist/cjs/services/CommentTimer.js.map +1 -0
  49. package/dist/cjs/services/CredentialStore.js +68 -0
  50. package/dist/cjs/services/CredentialStore.js.map +1 -0
  51. package/dist/cjs/services/CredentialWatcher.js +76 -0
  52. package/dist/cjs/services/CredentialWatcher.js.map +1 -0
  53. package/dist/cjs/services/Credentials.js +130 -0
  54. package/dist/cjs/services/Credentials.js.map +1 -0
  55. package/dist/cjs/services/EventLoop.js +203 -0
  56. package/dist/cjs/services/EventLoop.js.map +1 -0
  57. package/dist/cjs/services/GitHubClient/GitHubClient.js +236 -0
  58. package/dist/cjs/services/GitHubClient/GitHubClient.js.map +1 -0
  59. package/dist/cjs/services/GitHubClient/OctokitClient.js +329 -0
  60. package/dist/cjs/services/GitHubClient/OctokitClient.js.map +1 -0
  61. package/dist/cjs/services/GitHubClient.js +236 -0
  62. package/dist/cjs/services/GitHubClient.js.map +1 -0
  63. package/dist/cjs/services/GitHubEventSource.js +145 -0
  64. package/dist/cjs/services/GitHubEventSource.js.map +1 -0
  65. package/dist/cjs/services/GitHubIssueTracker.js +118 -0
  66. package/dist/cjs/services/GitHubIssueTracker.js.map +1 -0
  67. package/dist/cjs/services/LalphConfig.js +139 -0
  68. package/dist/cjs/services/LalphConfig.js.map +1 -0
  69. package/dist/cjs/services/LalphConfigReader.js +82 -0
  70. package/dist/cjs/services/LalphConfigReader.js.map +1 -0
  71. package/dist/cjs/services/LalphDirectory.js +45 -0
  72. package/dist/cjs/services/LalphDirectory.js.map +1 -0
  73. package/dist/cjs/services/LinearSdkClient.js +149 -0
  74. package/dist/cjs/services/LinearSdkClient.js.map +1 -0
  75. package/dist/cjs/services/LinearTracker.js +89 -0
  76. package/dist/cjs/services/LinearTracker.js.map +1 -0
  77. package/dist/cjs/services/MessengerAdapter/MessengerAdapter.js +30 -0
  78. package/dist/cjs/services/MessengerAdapter/MessengerAdapter.js.map +1 -0
  79. package/dist/cjs/services/MessengerAdapter/TelegramAdapter.js +131 -0
  80. package/dist/cjs/services/MessengerAdapter/TelegramAdapter.js.map +1 -0
  81. package/dist/cjs/services/MessengerAdapter/TelegramConfig.js +81 -0
  82. package/dist/cjs/services/MessengerAdapter/TelegramConfig.js.map +1 -0
  83. package/dist/cjs/services/MessengerAdapter.js +30 -0
  84. package/dist/cjs/services/MessengerAdapter.js.map +1 -0
  85. package/dist/cjs/services/OctokitClient.js +350 -0
  86. package/dist/cjs/services/OctokitClient.js.map +1 -0
  87. package/dist/cjs/services/PlanOverviewUploader.js +119 -0
  88. package/dist/cjs/services/PlanOverviewUploader.js.map +1 -0
  89. package/dist/cjs/services/PlanOverviewUploaderMap.js +25 -0
  90. package/dist/cjs/services/PlanOverviewUploaderMap.js.map +1 -0
  91. package/dist/cjs/services/PlanSession.js +489 -0
  92. package/dist/cjs/services/PlanSession.js.map +1 -0
  93. package/dist/cjs/services/ProjectStore.js +107 -0
  94. package/dist/cjs/services/ProjectStore.js.map +1 -0
  95. package/dist/cjs/services/PullRequestTracker.js +186 -0
  96. package/dist/cjs/services/PullRequestTracker.js.map +1 -0
  97. package/dist/cjs/services/SpecUploader.js +111 -0
  98. package/dist/cjs/services/SpecUploader.js.map +1 -0
  99. package/dist/cjs/services/SpecUploaderMap.js +25 -0
  100. package/dist/cjs/services/SpecUploaderMap.js.map +1 -0
  101. package/dist/cjs/services/TaskEventSource.js +58 -0
  102. package/dist/cjs/services/TaskEventSource.js.map +1 -0
  103. package/dist/cjs/services/TaskTracker/GitHubIssueTracker.js +155 -0
  104. package/dist/cjs/services/TaskTracker/GitHubIssueTracker.js.map +1 -0
  105. package/dist/cjs/services/TaskTracker/LinearSdkClient.js +149 -0
  106. package/dist/cjs/services/TaskTracker/LinearSdkClient.js.map +1 -0
  107. package/dist/cjs/services/TaskTracker/LinearTracker.js +126 -0
  108. package/dist/cjs/services/TaskTracker/LinearTracker.js.map +1 -0
  109. package/dist/cjs/services/TaskTracker/TaskTracker.js +20 -0
  110. package/dist/cjs/services/TaskTracker/TaskTracker.js.map +1 -0
  111. package/dist/cjs/services/TaskTracker/TrackerLayerMap.js +27 -0
  112. package/dist/cjs/services/TaskTracker/TrackerLayerMap.js.map +1 -0
  113. package/dist/cjs/services/TaskTracker/buildEventStream.js +55 -0
  114. package/dist/cjs/services/TaskTracker/buildEventStream.js.map +1 -0
  115. package/dist/cjs/services/TaskTracker.js +20 -0
  116. package/dist/cjs/services/TaskTracker.js.map +1 -0
  117. package/dist/cjs/services/TelegramAdapter.js +125 -0
  118. package/dist/cjs/services/TelegramAdapter.js.map +1 -0
  119. package/dist/cjs/services/TelegramConfig.js +81 -0
  120. package/dist/cjs/services/TelegramConfig.js.map +1 -0
  121. package/dist/cjs/services/TelegramConfigStore.js +81 -0
  122. package/dist/cjs/services/TelegramConfigStore.js.map +1 -0
  123. package/dist/cjs/services/TelegramNotifier.js +50 -0
  124. package/dist/cjs/services/TelegramNotifier.js.map +1 -0
  125. package/dist/cjs/services/TrackerLayerMap.js +27 -0
  126. package/dist/cjs/services/TrackerLayerMap.js.map +1 -0
  127. package/dist/cjs/services/TrackerResolver.js +45 -0
  128. package/dist/cjs/services/TrackerResolver.js.map +1 -0
  129. package/dist/cjs/services/messenger/MessengerAdapter.js +30 -0
  130. package/dist/cjs/services/messenger/MessengerAdapter.js.map +1 -0
  131. package/dist/cjs/services/messenger/TelegramAdapter.js +125 -0
  132. package/dist/cjs/services/messenger/TelegramAdapter.js.map +1 -0
  133. package/dist/cjs/services/task-tracker/GitHubIssueTracker.js +157 -0
  134. package/dist/cjs/services/task-tracker/GitHubIssueTracker.js.map +1 -0
  135. package/dist/cjs/services/task-tracker/LinearTracker.js +127 -0
  136. package/dist/cjs/services/task-tracker/LinearTracker.js.map +1 -0
  137. package/dist/cjs/services/task-tracker/TaskTracker.js +20 -0
  138. package/dist/cjs/services/task-tracker/TaskTracker.js.map +1 -0
  139. package/dist/cjs/services/task-tracker/TrackerLayerMap.js +27 -0
  140. package/dist/cjs/services/task-tracker/TrackerLayerMap.js.map +1 -0
  141. package/dist/cjs/shim/bin.js +31 -0
  142. package/dist/cjs/shim/bin.js.map +1 -0
  143. package/dist/cjs/shim/main.js +217 -0
  144. package/dist/cjs/shim/main.js.map +1 -0
  145. package/dist/cjs/shim/parseArgs.js +45 -0
  146. package/dist/cjs/shim/parseArgs.js.map +1 -0
  147. package/dist/cjs/shim/schemas.js +35 -0
  148. package/dist/cjs/shim/schemas.js.map +1 -0
  149. package/dist/dts/Events.d.ts +108 -0
  150. package/dist/dts/Events.d.ts.map +1 -0
  151. package/dist/dts/LalphMain.d.ts +2 -0
  152. package/dist/dts/LalphMain.d.ts.map +1 -0
  153. package/dist/dts/Main.d.ts +2 -0
  154. package/dist/dts/Main.d.ts.map +1 -0
  155. package/dist/dts/index.d.ts +101 -0
  156. package/dist/dts/index.d.ts.map +1 -0
  157. package/dist/dts/lib/AnalysisPrompts.d.ts +12 -0
  158. package/dist/dts/lib/AnalysisPrompts.d.ts.map +1 -0
  159. package/dist/dts/lib/BranchParser.d.ts +40 -0
  160. package/dist/dts/lib/BranchParser.d.ts.map +1 -0
  161. package/dist/dts/lib/MermaidToPlantUml.d.ts +19 -0
  162. package/dist/dts/lib/MermaidToPlantUml.d.ts.map +1 -0
  163. package/dist/dts/lib/SpecHtmlGenerator.d.ts +18 -0
  164. package/dist/dts/lib/SpecHtmlGenerator.d.ts.map +1 -0
  165. package/dist/dts/lib/StreamJsonParser.d.ts +147 -0
  166. package/dist/dts/lib/StreamJsonParser.d.ts.map +1 -0
  167. package/dist/dts/lib/TelegramFormatter.d.ts +35 -0
  168. package/dist/dts/lib/TelegramFormatter.d.ts.map +1 -0
  169. package/dist/dts/lib/TelegraphHtml.d.ts +11 -0
  170. package/dist/dts/lib/TelegraphHtml.d.ts.map +1 -0
  171. package/dist/dts/lib/TelegraphMarkdown.d.ts +21 -0
  172. package/dist/dts/lib/TelegraphMarkdown.d.ts.map +1 -0
  173. package/dist/dts/schemas/CredentialSchemas.d.ts +41 -0
  174. package/dist/dts/schemas/CredentialSchemas.d.ts.map +1 -0
  175. package/dist/dts/schemas/GitHubSchemas.d.ts +130 -0
  176. package/dist/dts/schemas/GitHubSchemas.d.ts.map +1 -0
  177. package/dist/dts/schemas/LinearSchemas.d.ts +121 -0
  178. package/dist/dts/schemas/LinearSchemas.d.ts.map +1 -0
  179. package/dist/dts/schemas/ProjectSchemas.d.ts +40 -0
  180. package/dist/dts/schemas/ProjectSchemas.d.ts.map +1 -0
  181. package/dist/dts/schemas/TrackerSchemas.d.ts +57 -0
  182. package/dist/dts/schemas/TrackerSchemas.d.ts.map +1 -0
  183. package/dist/dts/services/AppContext.d.ts +40 -0
  184. package/dist/dts/services/AppContext.d.ts.map +1 -0
  185. package/dist/dts/services/AppRuntimeConfig.d.ts +51 -0
  186. package/dist/dts/services/AppRuntimeConfig.d.ts.map +1 -0
  187. package/dist/dts/services/AutoMerge.d.ts +42 -0
  188. package/dist/dts/services/AutoMerge.d.ts.map +1 -0
  189. package/dist/dts/services/ChatMachine.d.ts +478 -0
  190. package/dist/dts/services/ChatMachine.d.ts.map +1 -0
  191. package/dist/dts/services/CommentTimer.d.ts +44 -0
  192. package/dist/dts/services/CommentTimer.d.ts.map +1 -0
  193. package/dist/dts/services/CredentialStore.d.ts +43 -0
  194. package/dist/dts/services/CredentialStore.d.ts.map +1 -0
  195. package/dist/dts/services/CredentialWatcher.d.ts +41 -0
  196. package/dist/dts/services/CredentialWatcher.d.ts.map +1 -0
  197. package/dist/dts/services/Credentials.d.ts +44 -0
  198. package/dist/dts/services/Credentials.d.ts.map +1 -0
  199. package/dist/dts/services/EventLoop.d.ts +26 -0
  200. package/dist/dts/services/EventLoop.d.ts.map +1 -0
  201. package/dist/dts/services/GitHubClient/GitHubClient.d.ts +69 -0
  202. package/dist/dts/services/GitHubClient/GitHubClient.d.ts.map +1 -0
  203. package/dist/dts/services/GitHubClient/OctokitClient.d.ts +214 -0
  204. package/dist/dts/services/GitHubClient/OctokitClient.d.ts.map +1 -0
  205. package/dist/dts/services/GitHubClient.d.ts +69 -0
  206. package/dist/dts/services/GitHubClient.d.ts.map +1 -0
  207. package/dist/dts/services/GitHubEventSource.d.ts +43 -0
  208. package/dist/dts/services/GitHubEventSource.d.ts.map +1 -0
  209. package/dist/dts/services/GitHubIssueTracker.d.ts +9 -0
  210. package/dist/dts/services/GitHubIssueTracker.d.ts.map +1 -0
  211. package/dist/dts/services/LalphConfig.d.ts +44 -0
  212. package/dist/dts/services/LalphConfig.d.ts.map +1 -0
  213. package/dist/dts/services/LalphConfigReader.d.ts +66 -0
  214. package/dist/dts/services/LalphConfigReader.d.ts.map +1 -0
  215. package/dist/dts/services/LalphDirectory.d.ts +39 -0
  216. package/dist/dts/services/LalphDirectory.d.ts.map +1 -0
  217. package/dist/dts/services/LinearSdkClient.d.ts +71 -0
  218. package/dist/dts/services/LinearSdkClient.d.ts.map +1 -0
  219. package/dist/dts/services/LinearTracker.d.ts +9 -0
  220. package/dist/dts/services/LinearTracker.d.ts.map +1 -0
  221. package/dist/dts/services/MessengerAdapter/MessengerAdapter.d.ts +69 -0
  222. package/dist/dts/services/MessengerAdapter/MessengerAdapter.d.ts.map +1 -0
  223. package/dist/dts/services/MessengerAdapter/TelegramAdapter.d.ts +13 -0
  224. package/dist/dts/services/MessengerAdapter/TelegramAdapter.d.ts.map +1 -0
  225. package/dist/dts/services/MessengerAdapter/TelegramConfig.d.ts +58 -0
  226. package/dist/dts/services/MessengerAdapter/TelegramConfig.d.ts.map +1 -0
  227. package/dist/dts/services/MessengerAdapter.d.ts +69 -0
  228. package/dist/dts/services/MessengerAdapter.d.ts.map +1 -0
  229. package/dist/dts/services/OctokitClient.d.ts +232 -0
  230. package/dist/dts/services/OctokitClient.d.ts.map +1 -0
  231. package/dist/dts/services/PlanOverviewUploader.d.ts +55 -0
  232. package/dist/dts/services/PlanOverviewUploader.d.ts.map +1 -0
  233. package/dist/dts/services/PlanOverviewUploaderMap.d.ts +14 -0
  234. package/dist/dts/services/PlanOverviewUploaderMap.d.ts.map +1 -0
  235. package/dist/dts/services/PlanSession.d.ts +169 -0
  236. package/dist/dts/services/PlanSession.d.ts.map +1 -0
  237. package/dist/dts/services/ProjectStore.d.ts +50 -0
  238. package/dist/dts/services/ProjectStore.d.ts.map +1 -0
  239. package/dist/dts/services/PullRequestTracker.d.ts +42 -0
  240. package/dist/dts/services/PullRequestTracker.d.ts.map +1 -0
  241. package/dist/dts/services/SpecUploader.d.ts +51 -0
  242. package/dist/dts/services/SpecUploader.d.ts.map +1 -0
  243. package/dist/dts/services/SpecUploaderMap.d.ts +14 -0
  244. package/dist/dts/services/SpecUploaderMap.d.ts.map +1 -0
  245. package/dist/dts/services/TaskEventSource.d.ts +21 -0
  246. package/dist/dts/services/TaskEventSource.d.ts.map +1 -0
  247. package/dist/dts/services/TaskTracker/GitHubIssueTracker.d.ts +10 -0
  248. package/dist/dts/services/TaskTracker/GitHubIssueTracker.d.ts.map +1 -0
  249. package/dist/dts/services/TaskTracker/LinearSdkClient.d.ts +71 -0
  250. package/dist/dts/services/TaskTracker/LinearSdkClient.d.ts.map +1 -0
  251. package/dist/dts/services/TaskTracker/LinearTracker.d.ts +10 -0
  252. package/dist/dts/services/TaskTracker/LinearTracker.d.ts.map +1 -0
  253. package/dist/dts/services/TaskTracker/TaskTracker.d.ts +39 -0
  254. package/dist/dts/services/TaskTracker/TaskTracker.d.ts.map +1 -0
  255. package/dist/dts/services/TaskTracker/TrackerLayerMap.d.ts +14 -0
  256. package/dist/dts/services/TaskTracker/TrackerLayerMap.d.ts.map +1 -0
  257. package/dist/dts/services/TaskTracker/buildEventStream.d.ts +16 -0
  258. package/dist/dts/services/TaskTracker/buildEventStream.d.ts.map +1 -0
  259. package/dist/dts/services/TaskTracker.d.ts +38 -0
  260. package/dist/dts/services/TaskTracker.d.ts.map +1 -0
  261. package/dist/dts/services/TelegramAdapter.d.ts +13 -0
  262. package/dist/dts/services/TelegramAdapter.d.ts.map +1 -0
  263. package/dist/dts/services/TelegramConfig.d.ts +58 -0
  264. package/dist/dts/services/TelegramConfig.d.ts.map +1 -0
  265. package/dist/dts/services/TelegramConfigStore.d.ts +57 -0
  266. package/dist/dts/services/TelegramConfigStore.d.ts.map +1 -0
  267. package/dist/dts/services/TelegramNotifier.d.ts +40 -0
  268. package/dist/dts/services/TelegramNotifier.d.ts.map +1 -0
  269. package/dist/dts/services/TrackerLayerMap.d.ts +14 -0
  270. package/dist/dts/services/TrackerLayerMap.d.ts.map +1 -0
  271. package/dist/dts/services/TrackerResolver.d.ts +43 -0
  272. package/dist/dts/services/TrackerResolver.d.ts.map +1 -0
  273. package/dist/dts/services/messenger/MessengerAdapter.d.ts +69 -0
  274. package/dist/dts/services/messenger/MessengerAdapter.d.ts.map +1 -0
  275. package/dist/dts/services/messenger/TelegramAdapter.d.ts +13 -0
  276. package/dist/dts/services/messenger/TelegramAdapter.d.ts.map +1 -0
  277. package/dist/dts/services/task-tracker/GitHubIssueTracker.d.ts +10 -0
  278. package/dist/dts/services/task-tracker/GitHubIssueTracker.d.ts.map +1 -0
  279. package/dist/dts/services/task-tracker/LinearTracker.d.ts +10 -0
  280. package/dist/dts/services/task-tracker/LinearTracker.d.ts.map +1 -0
  281. package/dist/dts/services/task-tracker/TaskTracker.d.ts +38 -0
  282. package/dist/dts/services/task-tracker/TaskTracker.d.ts.map +1 -0
  283. package/dist/dts/services/task-tracker/TrackerLayerMap.d.ts +14 -0
  284. package/dist/dts/services/task-tracker/TrackerLayerMap.d.ts.map +1 -0
  285. package/dist/dts/shim/bin.d.ts +3 -0
  286. package/dist/dts/shim/bin.d.ts.map +1 -0
  287. package/dist/dts/shim/main.d.ts +36 -0
  288. package/dist/dts/shim/main.d.ts.map +1 -0
  289. package/dist/dts/shim/parseArgs.d.ts +11 -0
  290. package/dist/dts/shim/parseArgs.d.ts.map +1 -0
  291. package/dist/dts/shim/schemas.d.ts +55 -0
  292. package/dist/dts/shim/schemas.d.ts.map +1 -0
  293. package/dist/esm/Events.js +41 -0
  294. package/dist/esm/Events.js.map +1 -0
  295. package/dist/esm/LalphMain.js +56 -0
  296. package/dist/esm/LalphMain.js.map +1 -0
  297. package/dist/esm/Main.js +112 -0
  298. package/dist/esm/Main.js.map +1 -0
  299. package/dist/esm/index.js +101 -0
  300. package/dist/esm/index.js.map +1 -0
  301. package/dist/esm/lib/AnalysisPrompts.js +54 -0
  302. package/dist/esm/lib/AnalysisPrompts.js.map +1 -0
  303. package/dist/esm/lib/BranchParser.js +36 -0
  304. package/dist/esm/lib/BranchParser.js.map +1 -0
  305. package/dist/esm/lib/MermaidToPlantUml.js +89 -0
  306. package/dist/esm/lib/MermaidToPlantUml.js.map +1 -0
  307. package/dist/esm/lib/SpecHtmlGenerator.js +153 -0
  308. package/dist/esm/lib/SpecHtmlGenerator.js.map +1 -0
  309. package/dist/esm/lib/StreamJsonParser.js +79 -0
  310. package/dist/esm/lib/StreamJsonParser.js.map +1 -0
  311. package/dist/esm/lib/TelegramFormatter.js +114 -0
  312. package/dist/esm/lib/TelegramFormatter.js.map +1 -0
  313. package/dist/esm/lib/TelegraphHtml.js +57 -0
  314. package/dist/esm/lib/TelegraphHtml.js.map +1 -0
  315. package/dist/esm/lib/TelegraphMarkdown.js +338 -0
  316. package/dist/esm/lib/TelegraphMarkdown.js.map +1 -0
  317. package/dist/esm/package.json +4 -0
  318. package/dist/esm/schemas/CredentialSchemas.js +22 -0
  319. package/dist/esm/schemas/CredentialSchemas.js.map +1 -0
  320. package/dist/esm/schemas/GitHubSchemas.js +50 -0
  321. package/dist/esm/schemas/GitHubSchemas.js.map +1 -0
  322. package/dist/esm/schemas/LinearSchemas.js +52 -0
  323. package/dist/esm/schemas/LinearSchemas.js.map +1 -0
  324. package/dist/esm/schemas/ProjectSchemas.js +18 -0
  325. package/dist/esm/schemas/ProjectSchemas.js.map +1 -0
  326. package/dist/esm/schemas/TrackerSchemas.js +26 -0
  327. package/dist/esm/schemas/TrackerSchemas.js.map +1 -0
  328. package/dist/esm/services/AppContext.js +48 -0
  329. package/dist/esm/services/AppContext.js.map +1 -0
  330. package/dist/esm/services/AppRuntimeConfig.js +26 -0
  331. package/dist/esm/services/AppRuntimeConfig.js.map +1 -0
  332. package/dist/esm/services/AutoMerge.js +131 -0
  333. package/dist/esm/services/AutoMerge.js.map +1 -0
  334. package/dist/esm/services/ChatMachine.js +855 -0
  335. package/dist/esm/services/ChatMachine.js.map +1 -0
  336. package/dist/esm/services/CommentTimer.js +72 -0
  337. package/dist/esm/services/CommentTimer.js.map +1 -0
  338. package/dist/esm/services/CredentialStore.js +59 -0
  339. package/dist/esm/services/CredentialStore.js.map +1 -0
  340. package/dist/esm/services/CredentialWatcher.js +67 -0
  341. package/dist/esm/services/CredentialWatcher.js.map +1 -0
  342. package/dist/esm/services/Credentials.js +121 -0
  343. package/dist/esm/services/Credentials.js.map +1 -0
  344. package/dist/esm/services/EventLoop.js +128 -0
  345. package/dist/esm/services/EventLoop.js.map +1 -0
  346. package/dist/esm/services/GitHubClient/GitHubClient.js +227 -0
  347. package/dist/esm/services/GitHubClient/GitHubClient.js.map +1 -0
  348. package/dist/esm/services/GitHubClient/OctokitClient.js +320 -0
  349. package/dist/esm/services/GitHubClient/OctokitClient.js.map +1 -0
  350. package/dist/esm/services/GitHubClient.js +227 -0
  351. package/dist/esm/services/GitHubClient.js.map +1 -0
  352. package/dist/esm/services/GitHubEventSource.js +136 -0
  353. package/dist/esm/services/GitHubEventSource.js.map +1 -0
  354. package/dist/esm/services/GitHubIssueTracker.js +111 -0
  355. package/dist/esm/services/GitHubIssueTracker.js.map +1 -0
  356. package/dist/esm/services/LalphConfig.js +130 -0
  357. package/dist/esm/services/LalphConfig.js.map +1 -0
  358. package/dist/esm/services/LalphConfigReader.js +71 -0
  359. package/dist/esm/services/LalphConfigReader.js.map +1 -0
  360. package/dist/esm/services/LalphDirectory.js +36 -0
  361. package/dist/esm/services/LalphDirectory.js.map +1 -0
  362. package/dist/esm/services/LinearSdkClient.js +140 -0
  363. package/dist/esm/services/LinearSdkClient.js.map +1 -0
  364. package/dist/esm/services/LinearTracker.js +82 -0
  365. package/dist/esm/services/LinearTracker.js.map +1 -0
  366. package/dist/esm/services/MessengerAdapter/MessengerAdapter.js +21 -0
  367. package/dist/esm/services/MessengerAdapter/MessengerAdapter.js.map +1 -0
  368. package/dist/esm/services/MessengerAdapter/TelegramAdapter.js +124 -0
  369. package/dist/esm/services/MessengerAdapter/TelegramAdapter.js.map +1 -0
  370. package/dist/esm/services/MessengerAdapter/TelegramConfig.js +71 -0
  371. package/dist/esm/services/MessengerAdapter/TelegramConfig.js.map +1 -0
  372. package/dist/esm/services/MessengerAdapter.js +21 -0
  373. package/dist/esm/services/MessengerAdapter.js.map +1 -0
  374. package/dist/esm/services/OctokitClient.js +341 -0
  375. package/dist/esm/services/OctokitClient.js.map +1 -0
  376. package/dist/esm/services/PlanOverviewUploader.js +109 -0
  377. package/dist/esm/services/PlanOverviewUploader.js.map +1 -0
  378. package/dist/esm/services/PlanOverviewUploaderMap.js +17 -0
  379. package/dist/esm/services/PlanOverviewUploaderMap.js.map +1 -0
  380. package/dist/esm/services/PlanSession.js +471 -0
  381. package/dist/esm/services/PlanSession.js.map +1 -0
  382. package/dist/esm/services/ProjectStore.js +98 -0
  383. package/dist/esm/services/ProjectStore.js.map +1 -0
  384. package/dist/esm/services/PullRequestTracker.js +177 -0
  385. package/dist/esm/services/PullRequestTracker.js.map +1 -0
  386. package/dist/esm/services/SpecUploader.js +101 -0
  387. package/dist/esm/services/SpecUploader.js.map +1 -0
  388. package/dist/esm/services/SpecUploaderMap.js +17 -0
  389. package/dist/esm/services/SpecUploaderMap.js.map +1 -0
  390. package/dist/esm/services/TaskEventSource.js +50 -0
  391. package/dist/esm/services/TaskEventSource.js.map +1 -0
  392. package/dist/esm/services/TaskTracker/GitHubIssueTracker.js +148 -0
  393. package/dist/esm/services/TaskTracker/GitHubIssueTracker.js.map +1 -0
  394. package/dist/esm/services/TaskTracker/LinearSdkClient.js +140 -0
  395. package/dist/esm/services/TaskTracker/LinearSdkClient.js.map +1 -0
  396. package/dist/esm/services/TaskTracker/LinearTracker.js +119 -0
  397. package/dist/esm/services/TaskTracker/LinearTracker.js.map +1 -0
  398. package/dist/esm/services/TaskTracker/TaskTracker.js +12 -0
  399. package/dist/esm/services/TaskTracker/TaskTracker.js.map +1 -0
  400. package/dist/esm/services/TaskTracker/TrackerLayerMap.js +19 -0
  401. package/dist/esm/services/TaskTracker/TrackerLayerMap.js.map +1 -0
  402. package/dist/esm/services/TaskTracker/buildEventStream.js +47 -0
  403. package/dist/esm/services/TaskTracker/buildEventStream.js.map +1 -0
  404. package/dist/esm/services/TaskTracker.js +12 -0
  405. package/dist/esm/services/TaskTracker.js.map +1 -0
  406. package/dist/esm/services/TelegramAdapter.js +118 -0
  407. package/dist/esm/services/TelegramAdapter.js.map +1 -0
  408. package/dist/esm/services/TelegramConfig.js +71 -0
  409. package/dist/esm/services/TelegramConfig.js.map +1 -0
  410. package/dist/esm/services/TelegramConfigStore.js +71 -0
  411. package/dist/esm/services/TelegramConfigStore.js.map +1 -0
  412. package/dist/esm/services/TelegramNotifier.js +41 -0
  413. package/dist/esm/services/TelegramNotifier.js.map +1 -0
  414. package/dist/esm/services/TrackerLayerMap.js +19 -0
  415. package/dist/esm/services/TrackerLayerMap.js.map +1 -0
  416. package/dist/esm/services/TrackerResolver.js +36 -0
  417. package/dist/esm/services/TrackerResolver.js.map +1 -0
  418. package/dist/esm/services/messenger/MessengerAdapter.js +21 -0
  419. package/dist/esm/services/messenger/MessengerAdapter.js.map +1 -0
  420. package/dist/esm/services/messenger/TelegramAdapter.js +118 -0
  421. package/dist/esm/services/messenger/TelegramAdapter.js.map +1 -0
  422. package/dist/esm/services/task-tracker/GitHubIssueTracker.js +150 -0
  423. package/dist/esm/services/task-tracker/GitHubIssueTracker.js.map +1 -0
  424. package/dist/esm/services/task-tracker/LinearTracker.js +120 -0
  425. package/dist/esm/services/task-tracker/LinearTracker.js.map +1 -0
  426. package/dist/esm/services/task-tracker/TaskTracker.js +12 -0
  427. package/dist/esm/services/task-tracker/TaskTracker.js.map +1 -0
  428. package/dist/esm/services/task-tracker/TrackerLayerMap.js +19 -0
  429. package/dist/esm/services/task-tracker/TrackerLayerMap.js.map +1 -0
  430. package/dist/esm/shim/bin.js +28 -0
  431. package/dist/esm/shim/bin.js.map +1 -0
  432. package/dist/esm/shim/main.js +196 -0
  433. package/dist/esm/shim/main.js.map +1 -0
  434. package/dist/esm/shim/parseArgs.js +39 -0
  435. package/dist/esm/shim/parseArgs.js.map +1 -0
  436. package/dist/esm/shim/schemas.js +28 -0
  437. package/dist/esm/shim/schemas.js.map +1 -0
  438. package/lib/AnalysisPrompts/package.json +6 -0
  439. package/lib/BranchParser/package.json +6 -0
  440. package/lib/MermaidToPlantUml/package.json +6 -0
  441. package/lib/SpecHtmlGenerator/package.json +6 -0
  442. package/lib/StreamJsonParser/package.json +6 -0
  443. package/lib/TelegramFormatter/package.json +6 -0
  444. package/lib/TelegraphMarkdown/package.json +6 -0
  445. package/package.json +360 -0
  446. package/schemas/CredentialSchemas/package.json +6 -0
  447. package/schemas/GitHubSchemas/package.json +6 -0
  448. package/schemas/LinearSchemas/package.json +6 -0
  449. package/schemas/ProjectSchemas/package.json +6 -0
  450. package/schemas/TrackerSchemas/package.json +6 -0
  451. package/services/AppContext/package.json +6 -0
  452. package/services/AppRuntimeConfig/package.json +6 -0
  453. package/services/AutoMerge/package.json +6 -0
  454. package/services/ChatMachine/package.json +6 -0
  455. package/services/CommentTimer/package.json +6 -0
  456. package/services/EventLoop/package.json +6 -0
  457. package/services/GitHubClient/package.json +6 -0
  458. package/services/LalphConfig/package.json +6 -0
  459. package/services/LinearSdkClient/package.json +6 -0
  460. package/services/MessengerAdapter/MessengerAdapter/package.json +6 -0
  461. package/services/MessengerAdapter/TelegramAdapter/package.json +6 -0
  462. package/services/OctokitClient/package.json +6 -0
  463. package/services/PlanOverviewUploader/package.json +6 -0
  464. package/services/PlanOverviewUploaderMap/package.json +6 -0
  465. package/services/PlanSession/package.json +6 -0
  466. package/services/ProjectStore/package.json +6 -0
  467. package/services/PullRequestTracker/package.json +6 -0
  468. package/services/TaskTracker/GitHubIssueTracker/package.json +6 -0
  469. package/services/TaskTracker/LinearTracker/package.json +6 -0
  470. package/services/TaskTracker/TaskTracker/package.json +6 -0
  471. package/services/TelegramConfig/package.json +6 -0
  472. package/services/TrackerLayerMap/package.json +6 -0
  473. package/shim/bin/package.json +6 -0
  474. package/shim/main/package.json +6 -0
  475. package/shim/parseArgs/package.json +6 -0
  476. package/shim/schemas/package.json +6 -0
  477. package/src/Events.ts +98 -0
  478. package/src/Main.ts +177 -0
  479. package/src/index.ts +124 -0
  480. package/src/lib/AnalysisPrompts.ts +54 -0
  481. package/src/lib/BranchParser.ts +58 -0
  482. package/src/lib/MermaidToPlantUml.ts +103 -0
  483. package/src/lib/SpecHtmlGenerator.ts +199 -0
  484. package/src/lib/StreamJsonParser.ts +99 -0
  485. package/src/lib/TelegramFormatter.ts +151 -0
  486. package/src/lib/TelegraphMarkdown.ts +305 -0
  487. package/src/schemas/CredentialSchemas.ts +23 -0
  488. package/src/schemas/GitHubSchemas.ts +50 -0
  489. package/src/schemas/LinearSchemas.ts +57 -0
  490. package/src/schemas/ProjectSchemas.ts +18 -0
  491. package/src/schemas/TrackerSchemas.ts +27 -0
  492. package/src/services/AppContext.ts +72 -0
  493. package/src/services/AppRuntimeConfig.ts +23 -0
  494. package/src/services/AutoMerge.ts +198 -0
  495. package/src/services/ChatMachine.ts +911 -0
  496. package/src/services/CommentTimer.ts +133 -0
  497. package/src/services/EventLoop.ts +321 -0
  498. package/src/services/GitHubClient.ts +282 -0
  499. package/src/services/LalphConfig.ts +218 -0
  500. package/src/services/LinearSdkClient.ts +181 -0
  501. package/src/services/MessengerAdapter/MessengerAdapter.ts +53 -0
  502. package/src/services/MessengerAdapter/TelegramAdapter.ts +145 -0
  503. package/src/services/OctokitClient.ts +628 -0
  504. package/src/services/PlanOverviewUploader.ts +160 -0
  505. package/src/services/PlanOverviewUploaderMap.ts +17 -0
  506. package/src/services/PlanSession.ts +589 -0
  507. package/src/services/ProjectStore.ts +140 -0
  508. package/src/services/PullRequestTracker.ts +253 -0
  509. package/src/services/TaskTracker/GitHubIssueTracker.ts +162 -0
  510. package/src/services/TaskTracker/LinearTracker.ts +141 -0
  511. package/src/services/TaskTracker/TaskTracker.ts +34 -0
  512. package/src/services/TelegramConfig.ts +120 -0
  513. package/src/services/TrackerLayerMap.ts +19 -0
  514. package/src/shim/bin.ts +36 -0
  515. package/src/shim/main.ts +255 -0
  516. package/src/shim/parseArgs.ts +43 -0
  517. package/src/shim/schemas.ts +38 -0
@@ -0,0 +1,855 @@
1
+ /**
2
+ * Chat state machine using @effect/experimental/Machine
3
+ * @since 1.0.0
4
+ */
5
+ import * as Machine from "@effect/experimental/Machine";
6
+ import { Data, Effect, Option, Schema } from "effect";
7
+ import { getAnalysisPrompt } from "../lib/AnalysisPrompts.js";
8
+ import { markdownToTelegramHtml, splitMessage } from "../lib/TelegramFormatter.js";
9
+ import { MessengerAdapter } from "./MessengerAdapter/MessengerAdapter.js";
10
+ import { PlanOverviewUploader } from "./PlanOverviewUploader.js";
11
+ import { PlanSession } from "./PlanSession.js";
12
+ import { ProjectStore } from "./ProjectStore.js";
13
+ // ── Button labels ────────────────────────────────────────────────
14
+ export const PLAN_BUTTON_LABEL = "Plan";
15
+ export const DONE_BUTTON_LABEL = "Done";
16
+ export const FEATURE_BUTTON_LABEL = "Feature";
17
+ export const BUG_BUTTON_LABEL = "Bug";
18
+ export const REFACTOR_BUTTON_LABEL = "Refactor";
19
+ export const OTHER_BUTTON_LABEL = "Other";
20
+ export const APPROVE_BUTTON_LABEL = "Approve";
21
+ export const BUFFER_BUTTON_LABEL = "Buffer";
22
+ export const INTERRUPT_BUTTON_LABEL = "Interrupt";
23
+ export const DISCARD_BUTTON_LABEL = "Discard";
24
+ export const ABORT_BUTTON_LABEL = "Abort";
25
+ export const NEW_PROJECT_BUTTON_LABEL = "New project";
26
+ const MY_ANSWER_BUTTON_LABEL = "Custom answer";
27
+ const BACK_BUTTON_LABEL = "Back";
28
+ const PLAN_TYPE_LABELS = [FEATURE_BUTTON_LABEL, BUG_BUTTON_LABEL, REFACTOR_BUTTON_LABEL, OTHER_BUTTON_LABEL];
29
+ // ── Keyboards ────────────────────────────────────────────────────
30
+ export const IDLE_KEYBOARD = [{
31
+ label: PLAN_BUTTON_LABEL
32
+ }, {
33
+ label: NEW_PROJECT_BUTTON_LABEL
34
+ }];
35
+ const COLLECTING_KEYBOARD = [{
36
+ label: DONE_BUTTON_LABEL
37
+ }, {
38
+ label: ABORT_BUTTON_LABEL
39
+ }];
40
+ const SESSION_KEYBOARD = [{
41
+ label: ABORT_BUTTON_LABEL
42
+ }];
43
+ const SPEC_READY_KEYBOARD = [{
44
+ label: APPROVE_BUTTON_LABEL
45
+ }, {
46
+ label: ABORT_BUTTON_LABEL
47
+ }];
48
+ export class ReadyFlags extends Data.Class {}
49
+ export const ChatState = /*#__PURE__*/Data.taggedEnum();
50
+ const initialSessionRunning = (projectId, planType) => ChatState.SessionRunning({
51
+ projectId,
52
+ planType,
53
+ pendingAnswerCount: 0,
54
+ pendingOptionLabels: new Set(),
55
+ answersBuffer: [],
56
+ awaitingFreeTextAnswer: false,
57
+ lastQuestionMessage: Option.none(),
58
+ readyFlags: new ReadyFlags({
59
+ spec: false,
60
+ analysis: false,
61
+ idle: false
62
+ }),
63
+ analysisFollowUpSent: false
64
+ });
65
+ // ── Request types ────────────────────────────────────────────────
66
+ export class UserMessage extends /*#__PURE__*/Schema.TaggedRequest()("UserMessage", {
67
+ failure: Schema.Never,
68
+ success: Schema.Void,
69
+ payload: {
70
+ text: Schema.String
71
+ }
72
+ }) {}
73
+ export class PlanTextOutput extends /*#__PURE__*/Schema.TaggedRequest()("PlanTextOutput", {
74
+ failure: Schema.Never,
75
+ success: Schema.Void,
76
+ payload: {
77
+ text: Schema.String
78
+ }
79
+ }) {}
80
+ export class PlanQuestionReceived extends /*#__PURE__*/Schema.TaggedRequest()("PlanQuestionReceived", {
81
+ failure: Schema.Never,
82
+ success: Schema.Void,
83
+ payload: {
84
+ questions: /*#__PURE__*/Schema.Array(/*#__PURE__*/Schema.Struct({
85
+ question: Schema.String,
86
+ header: /*#__PURE__*/Schema.optional(Schema.String),
87
+ options: /*#__PURE__*/Schema.optional(/*#__PURE__*/Schema.Array(/*#__PURE__*/Schema.Struct({
88
+ label: Schema.String
89
+ })))
90
+ }))
91
+ }
92
+ }) {}
93
+ export class PlanSpecCreatedReq extends /*#__PURE__*/Schema.TaggedRequest()("PlanSpecCreatedReq", {
94
+ failure: Schema.Never,
95
+ success: Schema.Void,
96
+ payload: {}
97
+ }) {}
98
+ export class PlanSpecUpdatedReq extends /*#__PURE__*/Schema.TaggedRequest()("PlanSpecUpdatedReq", {
99
+ failure: Schema.Never,
100
+ success: Schema.Void,
101
+ payload: {}
102
+ }) {}
103
+ export class PlanAnalysisReadyReq extends /*#__PURE__*/Schema.TaggedRequest()("PlanAnalysisReadyReq", {
104
+ failure: Schema.Never,
105
+ success: Schema.Void,
106
+ payload: {}
107
+ }) {}
108
+ export class PlanAwaitingInputReq extends /*#__PURE__*/Schema.TaggedRequest()("PlanAwaitingInputReq", {
109
+ failure: Schema.Never,
110
+ success: Schema.Void,
111
+ payload: {}
112
+ }) {}
113
+ export class PlanCompletedReq extends /*#__PURE__*/Schema.TaggedRequest()("PlanCompletedReq", {
114
+ failure: Schema.Never,
115
+ success: Schema.Void,
116
+ payload: {}
117
+ }) {}
118
+ export class PlanFailedReq extends /*#__PURE__*/Schema.TaggedRequest()("PlanFailedReq", {
119
+ failure: Schema.Never,
120
+ success: Schema.Void,
121
+ payload: {
122
+ message: Schema.String
123
+ }
124
+ }) {}
125
+ const reply = state => [undefined, state];
126
+ export const chatMachine = /*#__PURE__*/Machine.make(/*#__PURE__*/Effect.gen(function* () {
127
+ // Capture services at init (closures — handlers have R = never)
128
+ const notifier = yield* MessengerAdapter;
129
+ const planSession = yield* PlanSession;
130
+ const projectStore = yield* ProjectStore;
131
+ const planOverviewUploader = yield* PlanOverviewUploader;
132
+ // ── Helpers ────────────────────────────────────────────────
133
+ const readSpecFiles = planType => planType === "Feature" ? planSession.readFeatureAnalysis.pipe(Effect.map(files => [{
134
+ name: "analysis.md",
135
+ content: files.analysis,
136
+ mermaid: false
137
+ }, {
138
+ name: "services.mmd",
139
+ content: files.services,
140
+ mermaid: true
141
+ }, {
142
+ name: "test.md",
143
+ content: files.test,
144
+ mermaid: false
145
+ }])) : planType === "Bug" ? planSession.readBugAnalysis.pipe(Effect.map(files => [{
146
+ name: "analysis.md",
147
+ content: files.analysis,
148
+ mermaid: false
149
+ }])) : planType === "Refactor" ? planSession.readRefactorAnalysis.pipe(Effect.map(files => [{
150
+ name: "analysis.md",
151
+ content: files.analysis,
152
+ mermaid: false
153
+ }])) : planSession.readDefaultAnalysis.pipe(Effect.map(files => [{
154
+ name: "analysis.md",
155
+ content: files.analysis,
156
+ mermaid: false
157
+ }]));
158
+ const sendSpecFilesRaw = files => Effect.forEach(files, file => {
159
+ const formatted = file.mermaid ? markdownToTelegramHtml(`\`\`\`mermaid\n${file.content}\n\`\`\``) : markdownToTelegramHtml(file.content);
160
+ const text = `<b>${file.name}</b>\n${formatted}`;
161
+ return Effect.forEach(splitMessage(text), chunk => notifier.sendMessage(chunk));
162
+ });
163
+ const sendSpecFiles = planType => Effect.gen(function* () {
164
+ const files = yield* readSpecFiles(planType);
165
+ yield* planOverviewUploader.upload({
166
+ files,
167
+ description: `Spec: ${planType}`
168
+ }).pipe(Effect.tap(result => notifier.sendMessage(`<a href="${result.url}">View spec</a>`)), Effect.catchTag("PlanOverviewUploaderError", err => Effect.gen(function* () {
169
+ yield* Effect.logError(`Spec upload failed, sending raw: ${err.message}`);
170
+ yield* sendSpecFilesRaw(files);
171
+ })));
172
+ });
173
+ const rejectSession = planSession.reject.pipe(Effect.tapError(err => Effect.logError(`Plan abort error: ${err.message}`)), Effect.orElseSucceed(() => undefined));
174
+ const abortToIdle = hasSession => Effect.gen(function* () {
175
+ if (hasSession) {
176
+ yield* rejectSession;
177
+ }
178
+ yield* Effect.log("Plan aborted");
179
+ yield* notifier.sendMessage({
180
+ text: "Plan aborted.",
181
+ replyKeyboard: IDLE_KEYBOARD
182
+ });
183
+ });
184
+ const submitAnswers = answers => Effect.gen(function* () {
185
+ const combined = answers.join("\n");
186
+ yield* Effect.log("Flushing batched answers to plan session");
187
+ yield* planSession.answer(combined).pipe(Effect.tapError(err => Effect.logError(`Plan answer error: ${err.message}`)), Effect.orElseSucceed(() => undefined));
188
+ });
189
+ const showFollowUpChoice = (text, projectId, planType, readyFlags, analysisFollowUpSent) => Effect.gen(function* () {
190
+ yield* Effect.log("Holding follow-up message, showing buffer/interrupt buttons");
191
+ yield* notifier.sendMessage({
192
+ text: "Send as follow-up or interrupt Claude?",
193
+ options: [{
194
+ label: BUFFER_BUTTON_LABEL
195
+ }, {
196
+ label: INTERRUPT_BUTTON_LABEL
197
+ }, {
198
+ label: DISCARD_BUTTON_LABEL
199
+ }]
200
+ });
201
+ return ChatState.AwaitingFollowUpDecision({
202
+ projectId,
203
+ planType,
204
+ message: text,
205
+ readyFlags,
206
+ analysisFollowUpSent
207
+ });
208
+ });
209
+ const checkAllReady = (projectId, planType, flags, analysisFollowUpSent) => Effect.gen(function* () {
210
+ if (!flags.spec || !flags.analysis || !flags.idle) {
211
+ return ChatState.SessionRunning({
212
+ projectId,
213
+ planType,
214
+ pendingAnswerCount: 0,
215
+ pendingOptionLabels: new Set(),
216
+ answersBuffer: [],
217
+ awaitingFreeTextAnswer: false,
218
+ lastQuestionMessage: Option.none(),
219
+ readyFlags: flags,
220
+ analysisFollowUpSent
221
+ });
222
+ }
223
+ yield* sendSpecFiles(planType).pipe(Effect.catchAll(err => Effect.logError(`Failed to send spec files: ${String(err)}`)));
224
+ yield* notifier.sendMessage({
225
+ text: "Spec ready. Reply with questions or approve to proceed.",
226
+ replyKeyboard: SPEC_READY_KEYBOARD
227
+ }).pipe(Effect.orElseSucceed(() => undefined));
228
+ return ChatState.SpecReady({
229
+ projectId,
230
+ planType,
231
+ readyFlags: flags,
232
+ analysisFollowUpSent
233
+ });
234
+ });
235
+ const maybeAnalysisFollowUp = (planType, alreadySent) => alreadySent ? Effect.succeed(true) : planSession.sendFollowUp(getAnalysisPrompt(planType)).pipe(Effect.tapError(err => Effect.logError(`Analysis follow-up error: ${err.message}`)), Effect.orElseSucceed(() => undefined), Effect.as(true));
236
+ /**
237
+ * Extract projectId, planType, readyFlags, and analysisFollowUpSent from any
238
+ * "active session" state (SessionRunning, AwaitingFollowUpDecision, SpecReady).
239
+ */
240
+ const extractActiveState = state => {
241
+ switch (state._tag) {
242
+ case "SessionRunning":
243
+ return Option.some({
244
+ projectId: state.projectId,
245
+ planType: state.planType,
246
+ readyFlags: state.readyFlags,
247
+ analysisFollowUpSent: state.analysisFollowUpSent
248
+ });
249
+ case "AwaitingFollowUpDecision":
250
+ return Option.some({
251
+ projectId: state.projectId,
252
+ planType: state.planType,
253
+ readyFlags: state.readyFlags,
254
+ analysisFollowUpSent: state.analysisFollowUpSent
255
+ });
256
+ case "SpecReady":
257
+ return Option.some({
258
+ projectId: state.projectId,
259
+ planType: state.planType,
260
+ readyFlags: state.readyFlags,
261
+ analysisFollowUpSent: state.analysisFollowUpSent
262
+ });
263
+ default:
264
+ return Option.none();
265
+ }
266
+ };
267
+ // ── Procedure handlers ─────────────────────────────────────
268
+ return Machine.procedures.make(ChatState.Idle()).pipe(
269
+ // ── UserMessage ────────────────────────────────────────
270
+ Machine.procedures.add()("UserMessage", ctx => Effect.gen(function* () {
271
+ const {
272
+ state
273
+ } = ctx;
274
+ const text = ctx.request.text;
275
+ yield* Effect.log(`Incoming message: ${text}`);
276
+ switch (state._tag) {
277
+ case "Idle":
278
+ {
279
+ if (text === PLAN_BUTTON_LABEL) {
280
+ const projects = yield* projectStore.listProjects.pipe(Effect.orElseSucceed(() => []));
281
+ if (projects.length === 0) {
282
+ yield* notifier.sendMessage("No projects. Create one first.");
283
+ return reply(state);
284
+ }
285
+ if (projects.length === 1) {
286
+ yield* Effect.log("Single project auto-selected").pipe(Effect.annotateLogs("projectId", projects[0].id));
287
+ yield* notifier.sendMessage({
288
+ text: "What type of change?",
289
+ options: [...PLAN_TYPE_LABELS.map(label => ({
290
+ label
291
+ })), {
292
+ label: ABORT_BUTTON_LABEL
293
+ }]
294
+ });
295
+ return reply(ChatState.SelectingPlanType({
296
+ projectId: projects[0].id
297
+ }));
298
+ }
299
+ yield* notifier.sendMessage({
300
+ text: "Select a project:",
301
+ options: [...projects.map(p => ({
302
+ label: p.id
303
+ })), {
304
+ label: NEW_PROJECT_BUTTON_LABEL
305
+ }, {
306
+ label: ABORT_BUTTON_LABEL
307
+ }]
308
+ });
309
+ return reply(ChatState.SelectingProject());
310
+ }
311
+ if (text === NEW_PROJECT_BUTTON_LABEL) {
312
+ yield* notifier.sendMessage("Enter project name:");
313
+ return reply(ChatState.CreatingProject({
314
+ step: "Name",
315
+ data: {},
316
+ continueWithPlan: false
317
+ }));
318
+ }
319
+ return reply(state);
320
+ }
321
+ case "SelectingProject":
322
+ {
323
+ if (text === ABORT_BUTTON_LABEL) {
324
+ yield* notifier.sendMessage({
325
+ text: "Plan aborted.",
326
+ replyKeyboard: IDLE_KEYBOARD
327
+ });
328
+ return reply(ChatState.Idle());
329
+ }
330
+ if (text === NEW_PROJECT_BUTTON_LABEL) {
331
+ yield* notifier.sendMessage("Enter project name:");
332
+ return reply(ChatState.CreatingProject({
333
+ step: "Name",
334
+ data: {},
335
+ continueWithPlan: true
336
+ }));
337
+ }
338
+ yield* Effect.log("Project selected").pipe(Effect.annotateLogs("projectId", text));
339
+ yield* notifier.sendMessage({
340
+ text: "What type of change?",
341
+ options: [...PLAN_TYPE_LABELS.map(label => ({
342
+ label
343
+ })), {
344
+ label: ABORT_BUTTON_LABEL
345
+ }]
346
+ });
347
+ return reply(ChatState.SelectingPlanType({
348
+ projectId: text
349
+ }));
350
+ }
351
+ case "SelectingPlanType":
352
+ {
353
+ if (text === ABORT_BUTTON_LABEL) {
354
+ yield* notifier.sendMessage({
355
+ text: "Plan aborted.",
356
+ replyKeyboard: IDLE_KEYBOARD
357
+ });
358
+ return reply(ChatState.Idle());
359
+ }
360
+ if (PLAN_TYPE_LABELS.includes(text)) {
361
+ yield* Effect.log("Plan type selected, collection started").pipe(Effect.annotateLogs("planType", text));
362
+ yield* notifier.sendMessage({
363
+ text: "Describe what you'd like to plan. Tap <b>Done</b> when ready.",
364
+ replyKeyboard: COLLECTING_KEYBOARD
365
+ });
366
+ return reply(ChatState.CollectingPlan({
367
+ projectId: state.projectId,
368
+ planType: text,
369
+ buffer: []
370
+ }));
371
+ }
372
+ return reply(state);
373
+ }
374
+ case "CollectingPlan":
375
+ {
376
+ if (text === ABORT_BUTTON_LABEL) {
377
+ yield* abortToIdle(false);
378
+ return reply(ChatState.Idle());
379
+ }
380
+ if (text === DONE_BUTTON_LABEL) {
381
+ const joinedText = state.buffer.join("\n");
382
+ if (joinedText.trim().length === 0) {
383
+ yield* Effect.log("Plan collection done with empty buffer");
384
+ yield* notifier.sendMessage("No plan description provided.");
385
+ return reply(state);
386
+ }
387
+ yield* Effect.log("Plan collection done, starting session").pipe(Effect.annotateLogs("planText", joinedText));
388
+ const totalProjects = yield* projectStore.listProjects.pipe(Effect.map(ps => ps.length), Effect.orElseSucceed(() => 1));
389
+ yield* planSession.start(joinedText, totalProjects > 1 ? state.projectId : undefined).pipe(Effect.tapError(err => notifier.sendMessage(`Plan error: ${err.message}`)), Effect.orElseSucceed(() => undefined));
390
+ yield* notifier.sendMessage({
391
+ text: "Planning started...",
392
+ replyKeyboard: SESSION_KEYBOARD
393
+ });
394
+ return reply(initialSessionRunning(state.projectId, state.planType));
395
+ }
396
+ yield* Effect.log("Buffering plan message").pipe(Effect.annotateLogs("bufferedText", text));
397
+ yield* notifier.sendMessage("✓ Added. Tap <b>Done</b> when ready.");
398
+ return reply(ChatState.CollectingPlan({
399
+ projectId: state.projectId,
400
+ planType: state.planType,
401
+ buffer: [...state.buffer, text]
402
+ }));
403
+ }
404
+ case "SessionRunning":
405
+ {
406
+ if (text === ABORT_BUTTON_LABEL) {
407
+ yield* abortToIdle(true);
408
+ return reply(ChatState.Idle());
409
+ }
410
+ if (state.pendingAnswerCount > 0 && state.pendingOptionLabels.has(text)) {
411
+ if (text === MY_ANSWER_BUTTON_LABEL) {
412
+ yield* notifier.sendMessage({
413
+ text: "Type your answer:",
414
+ options: [{
415
+ label: BACK_BUTTON_LABEL
416
+ }]
417
+ });
418
+ return reply(ChatState.SessionRunning({
419
+ ...state,
420
+ awaitingFreeTextAnswer: true
421
+ }));
422
+ }
423
+ if (text === BACK_BUTTON_LABEL) {
424
+ if (Option.isSome(state.lastQuestionMessage)) {
425
+ yield* notifier.sendMessage(state.lastQuestionMessage.value);
426
+ }
427
+ return reply(ChatState.SessionRunning({
428
+ ...state,
429
+ awaitingFreeTextAnswer: false
430
+ }));
431
+ }
432
+ const newBuffer = [...state.answersBuffer, text];
433
+ const newPending = state.pendingAnswerCount - 1;
434
+ if (newPending <= 0) {
435
+ yield* Effect.log("Buffering answer");
436
+ yield* submitAnswers(newBuffer);
437
+ return reply(ChatState.SessionRunning({
438
+ ...state,
439
+ awaitingFreeTextAnswer: false,
440
+ answersBuffer: [],
441
+ pendingAnswerCount: 0,
442
+ pendingOptionLabels: new Set(),
443
+ readyFlags: new ReadyFlags({
444
+ ...state.readyFlags,
445
+ idle: false
446
+ })
447
+ }));
448
+ }
449
+ yield* Effect.log("Buffering answer");
450
+ return reply(ChatState.SessionRunning({
451
+ ...state,
452
+ awaitingFreeTextAnswer: false,
453
+ answersBuffer: newBuffer,
454
+ pendingAnswerCount: newPending
455
+ }));
456
+ }
457
+ if (state.awaitingFreeTextAnswer) {
458
+ const newBuffer = [...state.answersBuffer, text];
459
+ const newPending = state.pendingAnswerCount - 1;
460
+ if (newPending <= 0) {
461
+ yield* Effect.log("Buffering free-text answer");
462
+ yield* submitAnswers(newBuffer);
463
+ return reply(ChatState.SessionRunning({
464
+ ...state,
465
+ awaitingFreeTextAnswer: false,
466
+ answersBuffer: [],
467
+ pendingAnswerCount: 0,
468
+ pendingOptionLabels: new Set(),
469
+ readyFlags: new ReadyFlags({
470
+ ...state.readyFlags,
471
+ idle: false
472
+ })
473
+ }));
474
+ }
475
+ yield* Effect.log("Buffering free-text answer");
476
+ return reply(ChatState.SessionRunning({
477
+ ...state,
478
+ awaitingFreeTextAnswer: false,
479
+ answersBuffer: newBuffer,
480
+ pendingAnswerCount: newPending
481
+ }));
482
+ }
483
+ const idle = yield* planSession.isIdle;
484
+ if (idle) {
485
+ yield* planSession.sendFollowUp(text).pipe(Effect.tap(() => notifier.sendMessage("Follow-up sent.")), Effect.tapError(err => Effect.logError(`Plan follow-up error: ${err.message}`)), Effect.orElseSucceed(() => undefined));
486
+ return reply(ChatState.SessionRunning({
487
+ ...state,
488
+ readyFlags: new ReadyFlags({
489
+ ...state.readyFlags,
490
+ idle: false
491
+ })
492
+ }));
493
+ }
494
+ const newState = yield* showFollowUpChoice(text, state.projectId, state.planType, state.readyFlags, state.analysisFollowUpSent);
495
+ return reply(newState);
496
+ }
497
+ case "AwaitingFollowUpDecision":
498
+ {
499
+ if (text === BUFFER_BUTTON_LABEL) {
500
+ yield* Effect.log("Buffering follow-up message");
501
+ yield* planSession.sendFollowUp(state.message).pipe(Effect.tap(() => notifier.sendMessage("Message buffered — Claude will process it shortly.")), Effect.tapError(err => Effect.logError(`Plan follow-up error: ${err.message}`)), Effect.orElseSucceed(() => undefined));
502
+ return reply(ChatState.SessionRunning({
503
+ projectId: state.projectId,
504
+ planType: state.planType,
505
+ pendingAnswerCount: 0,
506
+ pendingOptionLabels: new Set(),
507
+ answersBuffer: [],
508
+ awaitingFreeTextAnswer: false,
509
+ lastQuestionMessage: Option.none(),
510
+ readyFlags: new ReadyFlags({
511
+ ...state.readyFlags,
512
+ idle: false
513
+ }),
514
+ analysisFollowUpSent: state.analysisFollowUpSent
515
+ }));
516
+ }
517
+ if (text === INTERRUPT_BUTTON_LABEL) {
518
+ yield* Effect.log("Interrupting Claude with follow-up message");
519
+ yield* planSession.interrupt(state.message).pipe(Effect.tap(() => notifier.sendMessage("Claude interrupted — processing your message now.")), Effect.tapError(err => Effect.logError(`Plan interrupt error: ${err.message}`)), Effect.orElseSucceed(() => undefined));
520
+ return reply(ChatState.SessionRunning({
521
+ projectId: state.projectId,
522
+ planType: state.planType,
523
+ pendingAnswerCount: 0,
524
+ pendingOptionLabels: new Set(),
525
+ answersBuffer: [],
526
+ awaitingFreeTextAnswer: false,
527
+ lastQuestionMessage: Option.none(),
528
+ readyFlags: new ReadyFlags({
529
+ ...state.readyFlags,
530
+ idle: false
531
+ }),
532
+ analysisFollowUpSent: state.analysisFollowUpSent
533
+ }));
534
+ }
535
+ if (text === DISCARD_BUTTON_LABEL) {
536
+ yield* Effect.log("Follow-up message discarded");
537
+ yield* notifier.sendMessage("Message discarded.");
538
+ return reply(ChatState.SessionRunning({
539
+ projectId: state.projectId,
540
+ planType: state.planType,
541
+ pendingAnswerCount: 0,
542
+ pendingOptionLabels: new Set(),
543
+ answersBuffer: [],
544
+ awaitingFreeTextAnswer: false,
545
+ lastQuestionMessage: Option.none(),
546
+ readyFlags: state.readyFlags,
547
+ analysisFollowUpSent: state.analysisFollowUpSent
548
+ }));
549
+ }
550
+ if (text === ABORT_BUTTON_LABEL) {
551
+ yield* abortToIdle(true);
552
+ return reply(ChatState.Idle());
553
+ }
554
+ return reply(state);
555
+ }
556
+ case "SpecReady":
557
+ {
558
+ if (text === APPROVE_BUTTON_LABEL) {
559
+ yield* Effect.log("User approved task creation");
560
+ yield* planSession.approve.pipe(Effect.tapError(err => Effect.logError(`Plan approve error: ${err.message}`)), Effect.orElseSucceed(() => undefined));
561
+ yield* notifier.sendMessage({
562
+ text: "Spec approved.",
563
+ replyKeyboard: IDLE_KEYBOARD
564
+ });
565
+ return reply(ChatState.Idle());
566
+ }
567
+ if (text === ABORT_BUTTON_LABEL) {
568
+ yield* abortToIdle(true);
569
+ return reply(ChatState.Idle());
570
+ }
571
+ const idleSpec = yield* planSession.isIdle;
572
+ if (idleSpec) {
573
+ yield* planSession.sendFollowUp(text).pipe(Effect.tap(() => notifier.sendMessage("Follow-up sent.")), Effect.tapError(err => Effect.logError(`Plan follow-up error: ${err.message}`)), Effect.orElseSucceed(() => undefined));
574
+ return reply(ChatState.SessionRunning({
575
+ projectId: state.projectId,
576
+ planType: state.planType,
577
+ pendingAnswerCount: 0,
578
+ pendingOptionLabels: new Set(),
579
+ answersBuffer: [],
580
+ awaitingFreeTextAnswer: false,
581
+ lastQuestionMessage: Option.none(),
582
+ readyFlags: new ReadyFlags({
583
+ ...state.readyFlags,
584
+ idle: false
585
+ }),
586
+ analysisFollowUpSent: state.analysisFollowUpSent
587
+ }));
588
+ }
589
+ const followUpState = yield* showFollowUpChoice(text, state.projectId, state.planType, state.readyFlags, state.analysisFollowUpSent);
590
+ return reply(followUpState);
591
+ }
592
+ case "CreatingProject":
593
+ {
594
+ if (text === ABORT_BUTTON_LABEL) {
595
+ yield* notifier.sendMessage({
596
+ text: "Project creation cancelled.",
597
+ replyKeyboard: IDLE_KEYBOARD
598
+ });
599
+ return reply(ChatState.Idle());
600
+ }
601
+ switch (state.step) {
602
+ case "Name":
603
+ {
604
+ yield* notifier.sendMessage({
605
+ text: "Concurrency (tasks in parallel):",
606
+ options: [{
607
+ label: "1"
608
+ }, {
609
+ label: "2"
610
+ }, {
611
+ label: "3"
612
+ }, {
613
+ label: "4"
614
+ }, {
615
+ label: ABORT_BUTTON_LABEL
616
+ }]
617
+ });
618
+ return reply(ChatState.CreatingProject({
619
+ ...state,
620
+ step: "Concurrency",
621
+ data: {
622
+ ...state.data,
623
+ name: text
624
+ }
625
+ }));
626
+ }
627
+ case "Concurrency":
628
+ {
629
+ const n = Number(text);
630
+ if (isNaN(n) || n < 1) return reply(state);
631
+ yield* notifier.sendMessage({
632
+ text: "Target branch (type branch name or skip):",
633
+ options: [{
634
+ label: "Skip"
635
+ }, {
636
+ label: ABORT_BUTTON_LABEL
637
+ }]
638
+ });
639
+ return reply(ChatState.CreatingProject({
640
+ ...state,
641
+ step: "TargetBranch",
642
+ data: {
643
+ ...state.data,
644
+ concurrency: n
645
+ }
646
+ }));
647
+ }
648
+ case "TargetBranch":
649
+ {
650
+ const targetBranch = text === "Skip" ? null : text;
651
+ yield* notifier.sendMessage({
652
+ text: "Git flow:",
653
+ options: [{
654
+ label: "PR"
655
+ }, {
656
+ label: "Commit"
657
+ }, {
658
+ label: ABORT_BUTTON_LABEL
659
+ }]
660
+ });
661
+ return reply(ChatState.CreatingProject({
662
+ ...state,
663
+ step: "GitFlow",
664
+ data: {
665
+ ...state.data,
666
+ targetBranch
667
+ }
668
+ }));
669
+ }
670
+ case "GitFlow":
671
+ {
672
+ const gitFlow = text === "Commit" ? "commit" : "pr";
673
+ yield* notifier.sendMessage({
674
+ text: "Enable review agent?",
675
+ options: [{
676
+ label: "Yes"
677
+ }, {
678
+ label: "No"
679
+ }, {
680
+ label: ABORT_BUTTON_LABEL
681
+ }]
682
+ });
683
+ return reply(ChatState.CreatingProject({
684
+ ...state,
685
+ step: "ReviewAgent",
686
+ data: {
687
+ ...state.data,
688
+ gitFlow
689
+ }
690
+ }));
691
+ }
692
+ case "ReviewAgent":
693
+ {
694
+ const reviewAgent = text === "Yes";
695
+ const data = state.data;
696
+ yield* projectStore.createProject({
697
+ id: data.name,
698
+ targetBranch: data.targetBranch != null ? Option.some(data.targetBranch) : Option.none(),
699
+ concurrency: data.concurrency,
700
+ gitFlow: data.gitFlow,
701
+ reviewAgent
702
+ }).pipe(Effect.tapError(err => notifier.sendMessage(`Failed to create project: ${err.message}`)), Effect.orElseSucceed(() => undefined));
703
+ yield* notifier.sendMessage(`Project <b>${data.name}</b> created.`);
704
+ if (state.continueWithPlan) {
705
+ yield* notifier.sendMessage({
706
+ text: "What type of change?",
707
+ options: [...PLAN_TYPE_LABELS.map(label => ({
708
+ label
709
+ })), {
710
+ label: ABORT_BUTTON_LABEL
711
+ }]
712
+ });
713
+ return reply(ChatState.SelectingPlanType({
714
+ projectId: data.name
715
+ }));
716
+ }
717
+ yield* notifier.sendMessage({
718
+ text: "Ready.",
719
+ replyKeyboard: IDLE_KEYBOARD
720
+ });
721
+ return reply(ChatState.Idle());
722
+ }
723
+ }
724
+ }
725
+ }
726
+ }).pipe(Effect.annotateLogs("service", "PlanInput"), Effect.tapError(err => Effect.logError(`Incoming message error: ${String(err)}`)), Effect.orElseSucceed(() => reply(ctx.state)))),
727
+ // ── PlanTextOutput ─────────────────────────────────────
728
+ Machine.procedures.add()("PlanTextOutput", ctx => Effect.gen(function* () {
729
+ yield* Effect.forEach(splitMessage(markdownToTelegramHtml(ctx.request.text)), chunk => notifier.sendMessage(chunk));
730
+ return reply(ctx.state);
731
+ }).pipe(Effect.tapError(err => Effect.logError(`Plan event relay error: ${String(err)}`)), Effect.orElseSucceed(() => reply(ctx.state)))),
732
+ // ── PlanQuestionReceived ───────────────────────────────
733
+ Machine.procedures.add()("PlanQuestionReceived", ctx => Effect.gen(function* () {
734
+ const {
735
+ request,
736
+ state
737
+ } = ctx;
738
+ if (state._tag !== "SessionRunning") {
739
+ return reply(state);
740
+ }
741
+ const labels = request.questions.flatMap(q => q.options?.map(o => o.label) ?? []);
742
+ const newPendingLabels = new Set([...labels, MY_ANSWER_BUTTON_LABEL, BACK_BUTTON_LABEL]);
743
+ let lastQ = Option.none();
744
+ yield* Effect.forEach(request.questions, q => {
745
+ const formatted = markdownToTelegramHtml(q.question);
746
+ const header = q.header != null ? `<b>${markdownToTelegramHtml(q.header)}</b>\n` : "";
747
+ const baseOptions = q.options?.map(o => ({
748
+ label: o.label
749
+ })) ?? [];
750
+ const msg = {
751
+ text: `${header}${formatted}`,
752
+ options: [...baseOptions, {
753
+ label: MY_ANSWER_BUTTON_LABEL
754
+ }]
755
+ };
756
+ lastQ = Option.some(msg);
757
+ return notifier.sendMessage(msg);
758
+ });
759
+ return reply(ChatState.SessionRunning({
760
+ ...state,
761
+ pendingAnswerCount: request.questions.length,
762
+ pendingOptionLabels: newPendingLabels,
763
+ answersBuffer: [],
764
+ awaitingFreeTextAnswer: false,
765
+ lastQuestionMessage: lastQ
766
+ }));
767
+ }).pipe(Effect.tapError(err => Effect.logError(`Plan event relay error: ${String(err)}`)), Effect.orElseSucceed(() => reply(ctx.state)))),
768
+ // ── PlanSpecCreatedReq ─────────────────────────────────
769
+ Machine.procedures.add()("PlanSpecCreatedReq", ctx => Effect.gen(function* () {
770
+ const active = extractActiveState(ctx.state);
771
+ if (Option.isNone(active)) return reply(ctx.state);
772
+ const {
773
+ analysisFollowUpSent,
774
+ planType,
775
+ projectId,
776
+ readyFlags
777
+ } = active.value;
778
+ const sent = yield* maybeAnalysisFollowUp(planType, analysisFollowUpSent);
779
+ const newFlags = new ReadyFlags({
780
+ ...readyFlags,
781
+ spec: true
782
+ });
783
+ const newState = yield* checkAllReady(projectId, planType, newFlags, sent);
784
+ return reply(newState);
785
+ }).pipe(Effect.tapError(err => Effect.logError(`Plan event relay error: ${String(err)}`)), Effect.orElseSucceed(() => reply(ctx.state)))),
786
+ // ── PlanSpecUpdatedReq ─────────────────────────────────
787
+ Machine.procedures.add()("PlanSpecUpdatedReq", ctx => Effect.gen(function* () {
788
+ const active = extractActiveState(ctx.state);
789
+ if (Option.isNone(active)) return reply(ctx.state);
790
+ const {
791
+ analysisFollowUpSent,
792
+ planType,
793
+ projectId,
794
+ readyFlags
795
+ } = active.value;
796
+ const sent = yield* maybeAnalysisFollowUp(planType, analysisFollowUpSent);
797
+ const newFlags = new ReadyFlags({
798
+ ...readyFlags,
799
+ spec: true
800
+ });
801
+ const newState = yield* checkAllReady(projectId, planType, newFlags, sent);
802
+ return reply(newState);
803
+ }).pipe(Effect.tapError(err => Effect.logError(`Plan event relay error: ${String(err)}`)), Effect.orElseSucceed(() => reply(ctx.state)))),
804
+ // ── PlanAnalysisReadyReq ───────────────────────────────
805
+ Machine.procedures.add()("PlanAnalysisReadyReq", ctx => Effect.gen(function* () {
806
+ const active = extractActiveState(ctx.state);
807
+ if (Option.isNone(active)) return reply(ctx.state);
808
+ const {
809
+ analysisFollowUpSent,
810
+ planType,
811
+ projectId,
812
+ readyFlags
813
+ } = active.value;
814
+ const newFlags = new ReadyFlags({
815
+ ...readyFlags,
816
+ analysis: true
817
+ });
818
+ const newState = yield* checkAllReady(projectId, planType, newFlags, analysisFollowUpSent);
819
+ return reply(newState);
820
+ }).pipe(Effect.tapError(err => Effect.logError(`Plan event relay error: ${String(err)}`)), Effect.orElseSucceed(() => reply(ctx.state)))),
821
+ // ── PlanAwaitingInputReq ───────────────────────────────
822
+ Machine.procedures.add()("PlanAwaitingInputReq", ctx => Effect.gen(function* () {
823
+ const active = extractActiveState(ctx.state);
824
+ if (Option.isNone(active)) return reply(ctx.state);
825
+ const {
826
+ analysisFollowUpSent,
827
+ planType,
828
+ projectId,
829
+ readyFlags
830
+ } = active.value;
831
+ const newFlags = new ReadyFlags({
832
+ ...readyFlags,
833
+ idle: true
834
+ });
835
+ const newState = yield* checkAllReady(projectId, planType, newFlags, analysisFollowUpSent);
836
+ return reply(newState);
837
+ }).pipe(Effect.tapError(err => Effect.logError(`Plan event relay error: ${String(err)}`)), Effect.orElseSucceed(() => reply(ctx.state)))),
838
+ // ── PlanCompletedReq ───────────────────────────────────
839
+ Machine.procedures.add()("PlanCompletedReq", ctx => Effect.gen(function* () {
840
+ yield* notifier.sendMessage({
841
+ text: "Plan completed.",
842
+ replyKeyboard: IDLE_KEYBOARD
843
+ });
844
+ return reply(ChatState.Idle());
845
+ }).pipe(Effect.tapError(err => Effect.logError(`Plan event relay error: ${String(err)}`)), Effect.orElseSucceed(() => reply(ctx.state)))),
846
+ // ── PlanFailedReq ──────────────────────────────────────
847
+ Machine.procedures.add()("PlanFailedReq", ctx => Effect.gen(function* () {
848
+ yield* notifier.sendMessage({
849
+ text: `Plan failed: ${ctx.request.message}`,
850
+ replyKeyboard: IDLE_KEYBOARD
851
+ });
852
+ return reply(ChatState.Idle());
853
+ }).pipe(Effect.tapError(err => Effect.logError(`Plan event relay error: ${String(err)}`)), Effect.orElseSucceed(() => reply(ctx.state)))));
854
+ }));
855
+ //# sourceMappingURL=ChatMachine.js.map