mstro-app 0.4.2 → 0.4.4

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 (342) hide show
  1. package/bin/mstro.js +119 -40
  2. package/dist/server/cli/headless/claude-invoker-process.d.ts +11 -0
  3. package/dist/server/cli/headless/claude-invoker-process.d.ts.map +1 -0
  4. package/dist/server/cli/headless/claude-invoker-process.js +140 -0
  5. package/dist/server/cli/headless/claude-invoker-process.js.map +1 -0
  6. package/dist/server/cli/headless/claude-invoker-stall.d.ts +40 -0
  7. package/dist/server/cli/headless/claude-invoker-stall.d.ts.map +1 -0
  8. package/dist/server/cli/headless/claude-invoker-stall.js +98 -0
  9. package/dist/server/cli/headless/claude-invoker-stall.js.map +1 -0
  10. package/dist/server/cli/headless/claude-invoker-stream.d.ts +44 -0
  11. package/dist/server/cli/headless/claude-invoker-stream.d.ts.map +1 -0
  12. package/dist/server/cli/headless/claude-invoker-stream.js +276 -0
  13. package/dist/server/cli/headless/claude-invoker-stream.js.map +1 -0
  14. package/dist/server/cli/headless/claude-invoker-tools.d.ts +21 -0
  15. package/dist/server/cli/headless/claude-invoker-tools.d.ts.map +1 -0
  16. package/dist/server/cli/headless/claude-invoker-tools.js +137 -0
  17. package/dist/server/cli/headless/claude-invoker-tools.js.map +1 -0
  18. package/dist/server/cli/headless/claude-invoker.d.ts +6 -4
  19. package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -1
  20. package/dist/server/cli/headless/claude-invoker.js +10 -804
  21. package/dist/server/cli/headless/claude-invoker.js.map +1 -1
  22. package/dist/server/cli/headless/haiku-assessments.d.ts +62 -0
  23. package/dist/server/cli/headless/haiku-assessments.d.ts.map +1 -0
  24. package/dist/server/cli/headless/haiku-assessments.js +281 -0
  25. package/dist/server/cli/headless/haiku-assessments.js.map +1 -0
  26. package/dist/server/cli/headless/headless-logger.d.ts +3 -2
  27. package/dist/server/cli/headless/headless-logger.d.ts.map +1 -1
  28. package/dist/server/cli/headless/headless-logger.js +28 -5
  29. package/dist/server/cli/headless/headless-logger.js.map +1 -1
  30. package/dist/server/cli/headless/native-timeout-detector.d.ts +44 -0
  31. package/dist/server/cli/headless/native-timeout-detector.d.ts.map +1 -0
  32. package/dist/server/cli/headless/native-timeout-detector.js +99 -0
  33. package/dist/server/cli/headless/native-timeout-detector.js.map +1 -0
  34. package/dist/server/cli/headless/stall-assessor.d.ts +2 -110
  35. package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
  36. package/dist/server/cli/headless/stall-assessor.js +65 -457
  37. package/dist/server/cli/headless/stall-assessor.js.map +1 -1
  38. package/dist/server/cli/headless/types.d.ts +4 -1
  39. package/dist/server/cli/headless/types.d.ts.map +1 -1
  40. package/dist/server/cli/improvisation-attachments.d.ts +21 -0
  41. package/dist/server/cli/improvisation-attachments.d.ts.map +1 -0
  42. package/dist/server/cli/improvisation-attachments.js +116 -0
  43. package/dist/server/cli/improvisation-attachments.js.map +1 -0
  44. package/dist/server/cli/improvisation-retry.d.ts +52 -0
  45. package/dist/server/cli/improvisation-retry.d.ts.map +1 -0
  46. package/dist/server/cli/improvisation-retry.js +434 -0
  47. package/dist/server/cli/improvisation-retry.js.map +1 -0
  48. package/dist/server/cli/improvisation-session-manager.d.ts +10 -266
  49. package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
  50. package/dist/server/cli/improvisation-session-manager.js +117 -1079
  51. package/dist/server/cli/improvisation-session-manager.js.map +1 -1
  52. package/dist/server/cli/improvisation-types.d.ts +86 -0
  53. package/dist/server/cli/improvisation-types.d.ts.map +1 -0
  54. package/dist/server/cli/improvisation-types.js +10 -0
  55. package/dist/server/cli/improvisation-types.js.map +1 -0
  56. package/dist/server/cli/prompt-builders.d.ts +68 -0
  57. package/dist/server/cli/prompt-builders.d.ts.map +1 -0
  58. package/dist/server/cli/prompt-builders.js +312 -0
  59. package/dist/server/cli/prompt-builders.js.map +1 -0
  60. package/dist/server/index.js +33 -212
  61. package/dist/server/index.js.map +1 -1
  62. package/dist/server/mcp/bouncer-haiku.d.ts +10 -0
  63. package/dist/server/mcp/bouncer-haiku.d.ts.map +1 -0
  64. package/dist/server/mcp/bouncer-haiku.js +152 -0
  65. package/dist/server/mcp/bouncer-haiku.js.map +1 -0
  66. package/dist/server/mcp/bouncer-integration.d.ts +3 -4
  67. package/dist/server/mcp/bouncer-integration.d.ts.map +1 -1
  68. package/dist/server/mcp/bouncer-integration.js +50 -196
  69. package/dist/server/mcp/bouncer-integration.js.map +1 -1
  70. package/dist/server/mcp/security-analysis.d.ts +38 -0
  71. package/dist/server/mcp/security-analysis.d.ts.map +1 -0
  72. package/dist/server/mcp/security-analysis.js +183 -0
  73. package/dist/server/mcp/security-analysis.js.map +1 -0
  74. package/dist/server/mcp/security-audit.d.ts +1 -1
  75. package/dist/server/mcp/security-audit.d.ts.map +1 -1
  76. package/dist/server/mcp/security-patterns.d.ts +1 -25
  77. package/dist/server/mcp/security-patterns.d.ts.map +1 -1
  78. package/dist/server/mcp/security-patterns.js +55 -260
  79. package/dist/server/mcp/security-patterns.js.map +1 -1
  80. package/dist/server/server-setup.d.ts +22 -0
  81. package/dist/server/server-setup.d.ts.map +1 -0
  82. package/dist/server/server-setup.js +101 -0
  83. package/dist/server/server-setup.js.map +1 -0
  84. package/dist/server/services/file-explorer-ops.d.ts +24 -0
  85. package/dist/server/services/file-explorer-ops.d.ts.map +1 -0
  86. package/dist/server/services/file-explorer-ops.js +211 -0
  87. package/dist/server/services/file-explorer-ops.js.map +1 -0
  88. package/dist/server/services/files.d.ts +2 -85
  89. package/dist/server/services/files.d.ts.map +1 -1
  90. package/dist/server/services/files.js +7 -427
  91. package/dist/server/services/files.js.map +1 -1
  92. package/dist/server/services/plan/composer.d.ts +1 -1
  93. package/dist/server/services/plan/composer.d.ts.map +1 -1
  94. package/dist/server/services/plan/composer.js +118 -32
  95. package/dist/server/services/plan/composer.js.map +1 -1
  96. package/dist/server/services/plan/config-installer.d.ts +25 -0
  97. package/dist/server/services/plan/config-installer.d.ts.map +1 -0
  98. package/dist/server/services/plan/config-installer.js +182 -0
  99. package/dist/server/services/plan/config-installer.js.map +1 -0
  100. package/dist/server/services/plan/dependency-resolver.d.ts +1 -1
  101. package/dist/server/services/plan/dependency-resolver.d.ts.map +1 -1
  102. package/dist/server/services/plan/dependency-resolver.js +4 -1
  103. package/dist/server/services/plan/dependency-resolver.js.map +1 -1
  104. package/dist/server/services/plan/executor.d.ts +38 -74
  105. package/dist/server/services/plan/executor.d.ts.map +1 -1
  106. package/dist/server/services/plan/executor.js +274 -460
  107. package/dist/server/services/plan/executor.js.map +1 -1
  108. package/dist/server/services/plan/front-matter.d.ts +18 -0
  109. package/dist/server/services/plan/front-matter.d.ts.map +1 -0
  110. package/dist/server/services/plan/front-matter.js +44 -0
  111. package/dist/server/services/plan/front-matter.js.map +1 -0
  112. package/dist/server/services/plan/output-manager.d.ts +22 -0
  113. package/dist/server/services/plan/output-manager.d.ts.map +1 -0
  114. package/dist/server/services/plan/output-manager.js +97 -0
  115. package/dist/server/services/plan/output-manager.js.map +1 -0
  116. package/dist/server/services/plan/parser-core.d.ts +20 -0
  117. package/dist/server/services/plan/parser-core.d.ts.map +1 -0
  118. package/dist/server/services/plan/parser-core.js +350 -0
  119. package/dist/server/services/plan/parser-core.js.map +1 -0
  120. package/dist/server/services/plan/parser-migration.d.ts +5 -0
  121. package/dist/server/services/plan/parser-migration.d.ts.map +1 -0
  122. package/dist/server/services/plan/parser-migration.js +124 -0
  123. package/dist/server/services/plan/parser-migration.js.map +1 -0
  124. package/dist/server/services/plan/parser.d.ts +11 -3
  125. package/dist/server/services/plan/parser.d.ts.map +1 -1
  126. package/dist/server/services/plan/parser.js +184 -369
  127. package/dist/server/services/plan/parser.js.map +1 -1
  128. package/dist/server/services/plan/prompt-builder.d.ts +17 -0
  129. package/dist/server/services/plan/prompt-builder.d.ts.map +1 -0
  130. package/dist/server/services/plan/prompt-builder.js +137 -0
  131. package/dist/server/services/plan/prompt-builder.js.map +1 -0
  132. package/dist/server/services/plan/review-gate.d.ts +28 -0
  133. package/dist/server/services/plan/review-gate.d.ts.map +1 -0
  134. package/dist/server/services/plan/review-gate.js +191 -0
  135. package/dist/server/services/plan/review-gate.js.map +1 -0
  136. package/dist/server/services/plan/state-reconciler.d.ts +1 -1
  137. package/dist/server/services/plan/state-reconciler.d.ts.map +1 -1
  138. package/dist/server/services/plan/state-reconciler.js +59 -7
  139. package/dist/server/services/plan/state-reconciler.js.map +1 -1
  140. package/dist/server/services/plan/types.d.ts +68 -0
  141. package/dist/server/services/plan/types.d.ts.map +1 -1
  142. package/dist/server/services/platform-credentials.d.ts +24 -0
  143. package/dist/server/services/platform-credentials.d.ts.map +1 -0
  144. package/dist/server/services/platform-credentials.js +68 -0
  145. package/dist/server/services/platform-credentials.js.map +1 -0
  146. package/dist/server/services/platform.d.ts +1 -31
  147. package/dist/server/services/platform.d.ts.map +1 -1
  148. package/dist/server/services/platform.js +11 -109
  149. package/dist/server/services/platform.js.map +1 -1
  150. package/dist/server/services/terminal/pty-manager.d.ts +7 -97
  151. package/dist/server/services/terminal/pty-manager.d.ts.map +1 -1
  152. package/dist/server/services/terminal/pty-manager.js +53 -266
  153. package/dist/server/services/terminal/pty-manager.js.map +1 -1
  154. package/dist/server/services/terminal/pty-utils.d.ts +57 -0
  155. package/dist/server/services/terminal/pty-utils.d.ts.map +1 -0
  156. package/dist/server/services/terminal/pty-utils.js +141 -0
  157. package/dist/server/services/terminal/pty-utils.js.map +1 -0
  158. package/dist/server/services/websocket/file-definition-handlers.d.ts +4 -0
  159. package/dist/server/services/websocket/file-definition-handlers.d.ts.map +1 -0
  160. package/dist/server/services/websocket/file-definition-handlers.js +153 -0
  161. package/dist/server/services/websocket/file-definition-handlers.js.map +1 -0
  162. package/dist/server/services/websocket/file-explorer-handlers.d.ts.map +1 -1
  163. package/dist/server/services/websocket/file-explorer-handlers.js +52 -391
  164. package/dist/server/services/websocket/file-explorer-handlers.js.map +1 -1
  165. package/dist/server/services/websocket/file-search-handlers.d.ts +5 -0
  166. package/dist/server/services/websocket/file-search-handlers.d.ts.map +1 -0
  167. package/dist/server/services/websocket/file-search-handlers.js +238 -0
  168. package/dist/server/services/websocket/file-search-handlers.js.map +1 -0
  169. package/dist/server/services/websocket/file-utils.js +3 -3
  170. package/dist/server/services/websocket/file-utils.js.map +1 -1
  171. package/dist/server/services/websocket/git-branch-handlers.d.ts +7 -0
  172. package/dist/server/services/websocket/git-branch-handlers.d.ts.map +1 -0
  173. package/dist/server/services/websocket/git-branch-handlers.js +110 -0
  174. package/dist/server/services/websocket/git-branch-handlers.js.map +1 -0
  175. package/dist/server/services/websocket/git-diff-handlers.d.ts +6 -0
  176. package/dist/server/services/websocket/git-diff-handlers.d.ts.map +1 -0
  177. package/dist/server/services/websocket/git-diff-handlers.js +123 -0
  178. package/dist/server/services/websocket/git-diff-handlers.js.map +1 -0
  179. package/dist/server/services/websocket/git-handlers.d.ts +2 -31
  180. package/dist/server/services/websocket/git-handlers.d.ts.map +1 -1
  181. package/dist/server/services/websocket/git-handlers.js +35 -541
  182. package/dist/server/services/websocket/git-handlers.js.map +1 -1
  183. package/dist/server/services/websocket/git-log-handlers.d.ts +6 -0
  184. package/dist/server/services/websocket/git-log-handlers.d.ts.map +1 -0
  185. package/dist/server/services/websocket/git-log-handlers.js +128 -0
  186. package/dist/server/services/websocket/git-log-handlers.js.map +1 -0
  187. package/dist/server/services/websocket/git-pr-handlers.d.ts.map +1 -1
  188. package/dist/server/services/websocket/git-pr-handlers.js +13 -53
  189. package/dist/server/services/websocket/git-pr-handlers.js.map +1 -1
  190. package/dist/server/services/websocket/git-tag-handlers.d.ts +6 -0
  191. package/dist/server/services/websocket/git-tag-handlers.d.ts.map +1 -0
  192. package/dist/server/services/websocket/git-tag-handlers.js +76 -0
  193. package/dist/server/services/websocket/git-tag-handlers.js.map +1 -0
  194. package/dist/server/services/websocket/git-utils.d.ts +43 -0
  195. package/dist/server/services/websocket/git-utils.d.ts.map +1 -0
  196. package/dist/server/services/websocket/git-utils.js +201 -0
  197. package/dist/server/services/websocket/git-utils.js.map +1 -0
  198. package/dist/server/services/websocket/handler.d.ts +2 -0
  199. package/dist/server/services/websocket/handler.d.ts.map +1 -1
  200. package/dist/server/services/websocket/handler.js +37 -112
  201. package/dist/server/services/websocket/handler.js.map +1 -1
  202. package/dist/server/services/websocket/plan-board-handlers.d.ts +11 -0
  203. package/dist/server/services/websocket/plan-board-handlers.d.ts.map +1 -0
  204. package/dist/server/services/websocket/plan-board-handlers.js +218 -0
  205. package/dist/server/services/websocket/plan-board-handlers.js.map +1 -0
  206. package/dist/server/services/websocket/plan-execution-handlers.d.ts +9 -0
  207. package/dist/server/services/websocket/plan-execution-handlers.d.ts.map +1 -0
  208. package/dist/server/services/websocket/plan-execution-handlers.js +142 -0
  209. package/dist/server/services/websocket/plan-execution-handlers.js.map +1 -0
  210. package/dist/server/services/websocket/plan-handlers.d.ts +7 -2
  211. package/dist/server/services/websocket/plan-handlers.d.ts.map +1 -1
  212. package/dist/server/services/websocket/plan-handlers.js +21 -462
  213. package/dist/server/services/websocket/plan-handlers.js.map +1 -1
  214. package/dist/server/services/websocket/plan-helpers.d.ts +19 -0
  215. package/dist/server/services/websocket/plan-helpers.d.ts.map +1 -0
  216. package/dist/server/services/websocket/plan-helpers.js +199 -0
  217. package/dist/server/services/websocket/plan-helpers.js.map +1 -0
  218. package/dist/server/services/websocket/plan-issue-handlers.d.ts +12 -0
  219. package/dist/server/services/websocket/plan-issue-handlers.d.ts.map +1 -0
  220. package/dist/server/services/websocket/plan-issue-handlers.js +162 -0
  221. package/dist/server/services/websocket/plan-issue-handlers.js.map +1 -0
  222. package/dist/server/services/websocket/plan-sprint-handlers.d.ts +7 -0
  223. package/dist/server/services/websocket/plan-sprint-handlers.d.ts.map +1 -0
  224. package/dist/server/services/websocket/plan-sprint-handlers.js +206 -0
  225. package/dist/server/services/websocket/plan-sprint-handlers.js.map +1 -0
  226. package/dist/server/services/websocket/quality-complexity.d.ts +14 -0
  227. package/dist/server/services/websocket/quality-complexity.d.ts.map +1 -0
  228. package/dist/server/services/websocket/quality-complexity.js +262 -0
  229. package/dist/server/services/websocket/quality-complexity.js.map +1 -0
  230. package/dist/server/services/websocket/quality-fix-agent.d.ts +16 -0
  231. package/dist/server/services/websocket/quality-fix-agent.d.ts.map +1 -0
  232. package/dist/server/services/websocket/quality-fix-agent.js +140 -0
  233. package/dist/server/services/websocket/quality-fix-agent.js.map +1 -0
  234. package/dist/server/services/websocket/quality-handlers.d.ts.map +1 -1
  235. package/dist/server/services/websocket/quality-handlers.js +34 -346
  236. package/dist/server/services/websocket/quality-handlers.js.map +1 -1
  237. package/dist/server/services/websocket/quality-linting.d.ts +9 -0
  238. package/dist/server/services/websocket/quality-linting.d.ts.map +1 -0
  239. package/dist/server/services/websocket/quality-linting.js +178 -0
  240. package/dist/server/services/websocket/quality-linting.js.map +1 -0
  241. package/dist/server/services/websocket/quality-review-agent.d.ts +19 -0
  242. package/dist/server/services/websocket/quality-review-agent.d.ts.map +1 -0
  243. package/dist/server/services/websocket/quality-review-agent.js +206 -0
  244. package/dist/server/services/websocket/quality-review-agent.js.map +1 -0
  245. package/dist/server/services/websocket/quality-service.d.ts +3 -51
  246. package/dist/server/services/websocket/quality-service.d.ts.map +1 -1
  247. package/dist/server/services/websocket/quality-service.js +9 -651
  248. package/dist/server/services/websocket/quality-service.js.map +1 -1
  249. package/dist/server/services/websocket/quality-tools.d.ts +23 -0
  250. package/dist/server/services/websocket/quality-tools.d.ts.map +1 -0
  251. package/dist/server/services/websocket/quality-tools.js +208 -0
  252. package/dist/server/services/websocket/quality-tools.js.map +1 -0
  253. package/dist/server/services/websocket/quality-types.d.ts +59 -0
  254. package/dist/server/services/websocket/quality-types.d.ts.map +1 -0
  255. package/dist/server/services/websocket/quality-types.js +101 -0
  256. package/dist/server/services/websocket/quality-types.js.map +1 -0
  257. package/dist/server/services/websocket/session-handlers.d.ts +3 -4
  258. package/dist/server/services/websocket/session-handlers.d.ts.map +1 -1
  259. package/dist/server/services/websocket/session-handlers.js +3 -378
  260. package/dist/server/services/websocket/session-handlers.js.map +1 -1
  261. package/dist/server/services/websocket/session-history.d.ts +4 -0
  262. package/dist/server/services/websocket/session-history.d.ts.map +1 -0
  263. package/dist/server/services/websocket/session-history.js +208 -0
  264. package/dist/server/services/websocket/session-history.js.map +1 -0
  265. package/dist/server/services/websocket/session-initialization.d.ts +5 -0
  266. package/dist/server/services/websocket/session-initialization.d.ts.map +1 -0
  267. package/dist/server/services/websocket/session-initialization.js +163 -0
  268. package/dist/server/services/websocket/session-initialization.js.map +1 -0
  269. package/dist/server/services/websocket/types.d.ts +12 -2
  270. package/dist/server/services/websocket/types.d.ts.map +1 -1
  271. package/package.json +1 -2
  272. package/server/cli/headless/claude-invoker-process.ts +204 -0
  273. package/server/cli/headless/claude-invoker-stall.ts +164 -0
  274. package/server/cli/headless/claude-invoker-stream.ts +353 -0
  275. package/server/cli/headless/claude-invoker-tools.ts +187 -0
  276. package/server/cli/headless/claude-invoker.ts +15 -1092
  277. package/server/cli/headless/haiku-assessments.ts +365 -0
  278. package/server/cli/headless/headless-logger.ts +26 -5
  279. package/server/cli/headless/native-timeout-detector.ts +117 -0
  280. package/server/cli/headless/stall-assessor.ts +65 -618
  281. package/server/cli/headless/types.ts +4 -1
  282. package/server/cli/improvisation-attachments.ts +148 -0
  283. package/server/cli/improvisation-retry.ts +602 -0
  284. package/server/cli/improvisation-session-manager.ts +140 -1349
  285. package/server/cli/improvisation-types.ts +98 -0
  286. package/server/cli/prompt-builders.ts +370 -0
  287. package/server/index.ts +35 -246
  288. package/server/mcp/bouncer-haiku.ts +182 -0
  289. package/server/mcp/bouncer-integration.ts +87 -248
  290. package/server/mcp/security-analysis.ts +217 -0
  291. package/server/mcp/security-audit.ts +1 -1
  292. package/server/mcp/security-patterns.ts +60 -283
  293. package/server/server-setup.ts +114 -0
  294. package/server/services/file-explorer-ops.ts +293 -0
  295. package/server/services/files.ts +20 -532
  296. package/server/services/plan/composer.ts +140 -35
  297. package/server/services/plan/config-installer.ts +187 -0
  298. package/server/services/plan/dependency-resolver.ts +4 -1
  299. package/server/services/plan/executor.ts +281 -488
  300. package/server/services/plan/front-matter.ts +48 -0
  301. package/server/services/plan/output-manager.ts +113 -0
  302. package/server/services/plan/parser-core.ts +406 -0
  303. package/server/services/plan/parser-migration.ts +128 -0
  304. package/server/services/plan/parser.ts +188 -394
  305. package/server/services/plan/prompt-builder.ts +161 -0
  306. package/server/services/plan/review-gate.ts +212 -0
  307. package/server/services/plan/state-reconciler.ts +68 -7
  308. package/server/services/plan/types.ts +101 -1
  309. package/server/services/platform-credentials.ts +83 -0
  310. package/server/services/platform.ts +16 -131
  311. package/server/services/terminal/pty-manager.ts +66 -313
  312. package/server/services/terminal/pty-utils.ts +176 -0
  313. package/server/services/websocket/file-definition-handlers.ts +165 -0
  314. package/server/services/websocket/file-explorer-handlers.ts +37 -452
  315. package/server/services/websocket/file-search-handlers.ts +291 -0
  316. package/server/services/websocket/file-utils.ts +3 -3
  317. package/server/services/websocket/git-branch-handlers.ts +130 -0
  318. package/server/services/websocket/git-diff-handlers.ts +140 -0
  319. package/server/services/websocket/git-handlers.ts +40 -625
  320. package/server/services/websocket/git-log-handlers.ts +149 -0
  321. package/server/services/websocket/git-pr-handlers.ts +17 -62
  322. package/server/services/websocket/git-tag-handlers.ts +91 -0
  323. package/server/services/websocket/git-utils.ts +230 -0
  324. package/server/services/websocket/handler.ts +39 -112
  325. package/server/services/websocket/plan-board-handlers.ts +277 -0
  326. package/server/services/websocket/plan-execution-handlers.ts +184 -0
  327. package/server/services/websocket/plan-handlers.ts +23 -544
  328. package/server/services/websocket/plan-helpers.ts +215 -0
  329. package/server/services/websocket/plan-issue-handlers.ts +204 -0
  330. package/server/services/websocket/plan-sprint-handlers.ts +252 -0
  331. package/server/services/websocket/quality-complexity.ts +294 -0
  332. package/server/services/websocket/quality-fix-agent.ts +181 -0
  333. package/server/services/websocket/quality-handlers.ts +36 -404
  334. package/server/services/websocket/quality-linting.ts +187 -0
  335. package/server/services/websocket/quality-review-agent.ts +246 -0
  336. package/server/services/websocket/quality-service.ts +11 -762
  337. package/server/services/websocket/quality-tools.ts +209 -0
  338. package/server/services/websocket/quality-types.ts +169 -0
  339. package/server/services/websocket/session-handlers.ts +5 -437
  340. package/server/services/websocket/session-history.ts +222 -0
  341. package/server/services/websocket/session-initialization.ts +209 -0
  342. package/server/services/websocket/types.ts +46 -2
@@ -0,0 +1,199 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ import { mkdirSync, writeFileSync } from 'node:fs';
4
+ import { join, resolve } from 'node:path';
5
+ import { PlanExecutor } from '../plan/executor.js';
6
+ import { defaultPmDir, resolvePmDir } from '../plan/parser.js';
7
+ import { PlanWatcher } from '../plan/watcher.js';
8
+ export const watcherCache = new Map();
9
+ export const executorCache = new Map();
10
+ /** Validate that a user-supplied path resolves within the .pm/ (or legacy .plan/) directory. */
11
+ export function resolvePlanPath(workingDir, relativePath) {
12
+ const pmDir = resolvePmDir(workingDir);
13
+ if (!pmDir)
14
+ return null;
15
+ const resolved = resolve(pmDir, relativePath);
16
+ if (!resolved.startsWith(`${pmDir}/`) && resolved !== pmDir)
17
+ return null;
18
+ return resolved;
19
+ }
20
+ /** Guard for write operations — returns true if denied. */
21
+ export function denyIfViewOnly(ctx, ws, permission) {
22
+ if (permission === 'view') {
23
+ ctx.send(ws, { type: 'planError', data: { error: 'Permission denied' } });
24
+ return true;
25
+ }
26
+ return false;
27
+ }
28
+ export function formatYamlValue(value) {
29
+ if (value === null || value === undefined)
30
+ return 'null';
31
+ if (typeof value === 'boolean')
32
+ return String(value);
33
+ if (typeof value === 'number')
34
+ return String(value);
35
+ if (Array.isArray(value)) {
36
+ if (value.length === 0)
37
+ return '[]';
38
+ return `[${value.map(v => typeof v === 'string' ? v : String(v)).join(', ')}]`;
39
+ }
40
+ return `"${String(value).replace(/"/g, '\\"')}"`;
41
+ }
42
+ export function buildIssueMarkdown(id, title, type, priority, labels, sprint, description) {
43
+ const labelsYaml = labels.length > 0 ? `[${labels.join(', ')}]` : '[]';
44
+ const today = new Date().toISOString().split('T')[0];
45
+ return `---
46
+ id: ${id}
47
+ title: "${title.replace(/"/g, '\\"')}"
48
+ type: ${type}
49
+ status: backlog
50
+ priority: ${priority}
51
+ estimate: null
52
+ labels: ${labelsYaml}
53
+ epic: null
54
+ sprint: ${sprint || 'null'}
55
+ milestone: null
56
+ assigned: null
57
+ created: "${today}"
58
+ due: null
59
+ blocked_by: []
60
+ blocks: []
61
+ relates_to: []
62
+ ---
63
+
64
+ # ${id}: ${title}
65
+
66
+ ## Description
67
+ ${description}
68
+
69
+ ## Acceptance Criteria
70
+
71
+ ## Technical Notes
72
+
73
+ ## Files to Modify
74
+
75
+ ## Activity
76
+ `;
77
+ }
78
+ function buildProjectMarkdown(name) {
79
+ const today = new Date().toISOString().split('T')[0];
80
+ const projectId = name.toLowerCase().replace(/[^a-z0-9]+/g, '-');
81
+ return `---
82
+ name: "${name}"
83
+ id: ${projectId}
84
+ created: "${today}"
85
+ status: active
86
+ estimation: fibonacci
87
+ id_prefixes:
88
+ epic: EP
89
+ issue: IS
90
+ bug: BG
91
+ labels: []
92
+ ---
93
+
94
+ # ${name}
95
+
96
+ ## Goals
97
+
98
+ ## Teams
99
+
100
+ ## Labels
101
+
102
+ ## Workflows
103
+ | Status | Category | Description |
104
+ |---|---|---|
105
+ | backlog | unstarted | Accepted, not yet scheduled |
106
+ | todo | unstarted | Scheduled for current sprint |
107
+ | in_progress | started | Actively being worked on |
108
+ | in_review | started | PR open, awaiting review |
109
+ | done | completed | Merged and verified |
110
+ | cancelled | cancelled | Will not be done |
111
+ `;
112
+ }
113
+ function buildStateMarkdown(name) {
114
+ return `---
115
+ project: "${name}"
116
+ current_sprint: null
117
+ active_milestone: null
118
+ paused: false
119
+ last_session: null
120
+ ---
121
+
122
+ # Project State
123
+
124
+ ## Current Focus
125
+
126
+ ## Ready to Work
127
+
128
+ ## In Progress
129
+
130
+ ## Blocked
131
+
132
+ ## Recently Completed
133
+
134
+ ## Warnings
135
+ `;
136
+ }
137
+ export function getWatcher(workingDir, ctx) {
138
+ let watcher = watcherCache.get(workingDir);
139
+ if (!watcher) {
140
+ watcher = new PlanWatcher(workingDir, ctx);
141
+ watcherCache.set(workingDir, watcher);
142
+ }
143
+ return watcher;
144
+ }
145
+ export function getExecutor(workingDir) {
146
+ let executor = executorCache.get(workingDir);
147
+ if (!executor) {
148
+ executor = new PlanExecutor(workingDir);
149
+ executorCache.set(workingDir, executor);
150
+ }
151
+ return executor;
152
+ }
153
+ /** Cleanup watchers and executors for a working directory. */
154
+ export function cleanupPlanResources(workingDir) {
155
+ const watcher = watcherCache.get(workingDir);
156
+ if (watcher) {
157
+ watcher.stop();
158
+ watcherCache.delete(workingDir);
159
+ }
160
+ const executor = executorCache.get(workingDir);
161
+ if (executor) {
162
+ executor.stop();
163
+ executorCache.delete(workingDir);
164
+ }
165
+ }
166
+ /** Create the .mstro/pm/ directory structure with a default board. */
167
+ export function scaffoldPmDirectory(workingDir, name) {
168
+ const planDir = defaultPmDir(workingDir);
169
+ const boardId = 'BOARD-001';
170
+ const boardDir = join(planDir, 'boards', boardId);
171
+ for (const dir of ['milestones', 'templates']) {
172
+ mkdirSync(join(planDir, dir), { recursive: true });
173
+ }
174
+ for (const dir of ['backlog', 'out', 'reviews', 'logs']) {
175
+ mkdirSync(join(boardDir, dir), { recursive: true });
176
+ }
177
+ writeFileSync(join(planDir, 'project.md'), buildProjectMarkdown(name), 'utf-8');
178
+ const workspace = { activeBoardId: boardId, boardOrder: [boardId] };
179
+ writeFileSync(join(planDir, 'workspace.json'), JSON.stringify(workspace, null, 2), 'utf-8');
180
+ const today = new Date().toISOString().split('T')[0];
181
+ writeFileSync(join(boardDir, 'board.md'), `---
182
+ id: ${boardId}
183
+ title: "Board 1"
184
+ status: draft
185
+ created: "${today}"
186
+ completed_at: null
187
+ goal: ""
188
+ ---
189
+
190
+ # Board 1
191
+
192
+ ## Goal
193
+
194
+ ## Notes
195
+ `, 'utf-8');
196
+ writeFileSync(join(boardDir, 'STATE.md'), buildStateMarkdown(name), 'utf-8');
197
+ writeFileSync(join(boardDir, 'progress.md'), '# Board Progress\n', 'utf-8');
198
+ }
199
+ //# sourceMappingURL=plan-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-helpers.js","sourceRoot":"","sources":["../../../../server/services/websocket/plan-helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { HandlerContext } from './handler-context.js';
2
+ import type { WebSocketMessage, WSContext } from './types.js';
3
+ export declare function handlePlanInit(ctx: HandlerContext, ws: WSContext, workingDir: string): void;
4
+ export declare function handleListIssues(ctx: HandlerContext, ws: WSContext, workingDir: string): void;
5
+ export declare function handleGetIssue(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string): void;
6
+ export declare function handleGetSprint(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string): void;
7
+ export declare function handleGetMilestone(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string): void;
8
+ export declare function handleCreateIssue(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string, permission?: 'control' | 'view'): void;
9
+ export declare function handleUpdateIssue(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string, permission?: 'control' | 'view'): void;
10
+ export declare function handleDeleteIssue(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string, permission?: 'control' | 'view'): void;
11
+ export declare function handleScaffold(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string, permission?: 'control' | 'view'): void;
12
+ //# sourceMappingURL=plan-issue-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-issue-handlers.d.ts","sourceRoot":"","sources":["../../../../server/services/websocket/plan-issue-handlers.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAM9D,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAgB3F;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAO7F;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAYlH;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAYnH;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAYtH;AA0BD,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EACzD,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,GAClD,IAAI,CAsBN;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EACzD,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,GAClD,IAAI,CA8BN;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EACzD,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,GAClD,IAAI,CAiBN;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EACzD,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,GAClD,IAAI,CAQN"}
@@ -0,0 +1,162 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
4
+ import { basename, join } from 'node:path';
5
+ import { replaceFrontMatterField } from '../plan/front-matter.js';
6
+ import { defaultPmDir, getNextId, parseBoardDirectory, parsePlanDirectory, parseSingleIssue, parseSingleMilestone, parseSingleSprint, planDirExists, resolvePmDir } from '../plan/parser.js';
7
+ import { buildIssueMarkdown, denyIfViewOnly, formatYamlValue, getWatcher, resolvePlanPath, scaffoldPmDirectory } from './plan-helpers.js';
8
+ // ============================================================================
9
+ // Read-only handlers
10
+ // ============================================================================
11
+ export function handlePlanInit(ctx, ws, workingDir) {
12
+ if (!planDirExists(workingDir)) {
13
+ const projectName = basename(workingDir) || 'My Project';
14
+ scaffoldPmDirectory(workingDir, projectName);
15
+ }
16
+ const fullState = parsePlanDirectory(workingDir);
17
+ if (!fullState) {
18
+ ctx.send(ws, { type: 'planNotFound', data: {} });
19
+ return;
20
+ }
21
+ ctx.send(ws, { type: 'planState', data: fullState });
22
+ const watcher = getWatcher(workingDir, ctx);
23
+ watcher.start();
24
+ }
25
+ export function handleListIssues(ctx, ws, workingDir) {
26
+ const fullState = parsePlanDirectory(workingDir);
27
+ if (!fullState) {
28
+ ctx.send(ws, { type: 'planNotFound', data: {} });
29
+ return;
30
+ }
31
+ ctx.send(ws, { type: 'planIssueList', data: { issues: fullState.issues } });
32
+ }
33
+ export function handleGetIssue(ctx, ws, msg, workingDir) {
34
+ const path = msg.data?.path;
35
+ if (!path || !resolvePlanPath(workingDir, path)) {
36
+ ctx.send(ws, { type: 'planError', data: { error: 'Invalid issue path' } });
37
+ return;
38
+ }
39
+ const issue = parseSingleIssue(workingDir, path);
40
+ if (!issue) {
41
+ ctx.send(ws, { type: 'planError', data: { error: `Issue not found: ${path}` } });
42
+ return;
43
+ }
44
+ ctx.send(ws, { type: 'planIssue', data: issue });
45
+ }
46
+ export function handleGetSprint(ctx, ws, msg, workingDir) {
47
+ const path = msg.data?.path;
48
+ if (!path || !resolvePlanPath(workingDir, path)) {
49
+ ctx.send(ws, { type: 'planError', data: { error: 'Invalid sprint path' } });
50
+ return;
51
+ }
52
+ const sprint = parseSingleSprint(workingDir, path);
53
+ if (!sprint) {
54
+ ctx.send(ws, { type: 'planError', data: { error: `Sprint not found: ${path}` } });
55
+ return;
56
+ }
57
+ ctx.send(ws, { type: 'planSprint', data: sprint });
58
+ }
59
+ export function handleGetMilestone(ctx, ws, msg, workingDir) {
60
+ const path = msg.data?.path;
61
+ if (!path || !resolvePlanPath(workingDir, path)) {
62
+ ctx.send(ws, { type: 'planError', data: { error: 'Invalid milestone path' } });
63
+ return;
64
+ }
65
+ const milestone = parseSingleMilestone(workingDir, path);
66
+ if (!milestone) {
67
+ ctx.send(ws, { type: 'planError', data: { error: `Milestone not found: ${path}` } });
68
+ return;
69
+ }
70
+ ctx.send(ws, { type: 'planMilestone', data: milestone });
71
+ }
72
+ // ============================================================================
73
+ // Mutation handlers
74
+ // ============================================================================
75
+ /** Resolve backlog directory and existing issues for a board or legacy layout. */
76
+ function resolveBacklogContext(pmDir, workingDir, boardId) {
77
+ const fullState = parsePlanDirectory(workingDir);
78
+ const effectiveBoardId = boardId || fullState?.workspace?.activeBoardId;
79
+ if (effectiveBoardId && existsSync(join(pmDir, 'boards', effectiveBoardId))) {
80
+ const boardState = parseBoardDirectory(pmDir, effectiveBoardId);
81
+ return {
82
+ backlogDir: join(pmDir, 'boards', effectiveBoardId, 'backlog'),
83
+ issues: boardState?.issues ?? [],
84
+ pathPrefix: `boards/${effectiveBoardId}/backlog`,
85
+ };
86
+ }
87
+ return {
88
+ backlogDir: join(pmDir, 'backlog'),
89
+ issues: fullState?.issues ?? [],
90
+ pathPrefix: 'backlog',
91
+ };
92
+ }
93
+ export function handleCreateIssue(ctx, ws, msg, workingDir, permission) {
94
+ if (denyIfViewOnly(ctx, ws, permission))
95
+ return;
96
+ const { title, type = 'issue', priority = 'P2', labels = [], sprint, description = '', boardId } = msg.data || {};
97
+ if (!title) {
98
+ ctx.send(ws, { type: 'planError', data: { error: 'Title required' } });
99
+ return;
100
+ }
101
+ const pmDir = resolvePmDir(workingDir) ?? defaultPmDir(workingDir);
102
+ const { backlogDir, issues, pathPrefix } = resolveBacklogContext(pmDir, workingDir, boardId);
103
+ if (!existsSync(backlogDir))
104
+ mkdirSync(backlogDir, { recursive: true });
105
+ const prefix = type === 'bug' ? 'BG' : type === 'epic' ? 'EP' : 'IS';
106
+ const id = getNextId(issues, prefix);
107
+ const fileName = `${id}.md`;
108
+ writeFileSync(join(backlogDir, fileName), buildIssueMarkdown(id, title, type, priority, labels, sprint, description), 'utf-8');
109
+ const issue = parseSingleIssue(workingDir, `${pathPrefix}/${fileName}`);
110
+ ctx.broadcastToAll({ type: 'planIssueCreated', data: issue });
111
+ }
112
+ export function handleUpdateIssue(ctx, ws, msg, workingDir, permission) {
113
+ if (denyIfViewOnly(ctx, ws, permission))
114
+ return;
115
+ const { path, fields } = msg.data || {};
116
+ if (!path || !fields) {
117
+ ctx.send(ws, { type: 'planError', data: { error: 'Path and fields required' } });
118
+ return;
119
+ }
120
+ const fullPath = resolvePlanPath(workingDir, path);
121
+ if (!fullPath || !existsSync(fullPath)) {
122
+ ctx.send(ws, { type: 'planError', data: { error: `File not found: ${path}` } });
123
+ return;
124
+ }
125
+ let content = readFileSync(fullPath, 'utf-8');
126
+ if (!content.match(/^---\n/)) {
127
+ ctx.send(ws, { type: 'planError', data: { error: 'Invalid file format' } });
128
+ return;
129
+ }
130
+ for (const [key, value] of Object.entries(fields)) {
131
+ const yamlKey = key.replace(/([A-Z])/g, '_$1').toLowerCase();
132
+ content = replaceFrontMatterField(content, yamlKey, formatYamlValue(value));
133
+ }
134
+ writeFileSync(fullPath, content, 'utf-8');
135
+ const issue = parseSingleIssue(workingDir, path);
136
+ ctx.broadcastToAll({ type: 'planIssueUpdated', data: issue });
137
+ }
138
+ export function handleDeleteIssue(ctx, ws, msg, workingDir, permission) {
139
+ if (denyIfViewOnly(ctx, ws, permission))
140
+ return;
141
+ const path = msg.data?.path;
142
+ if (!path) {
143
+ ctx.send(ws, { type: 'planError', data: { error: 'Path required' } });
144
+ return;
145
+ }
146
+ const fullPath = resolvePlanPath(workingDir, path);
147
+ if (!fullPath || !existsSync(fullPath)) {
148
+ ctx.send(ws, { type: 'planError', data: { error: `File not found: ${path}` } });
149
+ return;
150
+ }
151
+ unlinkSync(fullPath);
152
+ ctx.broadcastToAll({ type: 'planIssueDeleted', data: { path } });
153
+ }
154
+ export function handleScaffold(ctx, ws, msg, workingDir, permission) {
155
+ if (denyIfViewOnly(ctx, ws, permission))
156
+ return;
157
+ const name = msg.data?.name || 'My Project';
158
+ scaffoldPmDirectory(workingDir, name);
159
+ const fullState = parsePlanDirectory(workingDir);
160
+ ctx.broadcastToAll({ type: 'planScaffolded', data: fullState });
161
+ }
162
+ //# sourceMappingURL=plan-issue-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-issue-handlers.js","sourceRoot":"","sources":["../../../../server/services/websocket/plan-issue-handlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { HandlerContext } from './handler-context.js';
2
+ import type { WebSocketMessage, WSContext } from './types.js';
3
+ export declare function handleCreateSprint(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string, permission?: 'control' | 'view'): void;
4
+ export declare function handleActivateSprint(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string, permission?: 'control' | 'view'): void;
5
+ export declare function handleCompleteSprint(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string, permission?: 'control' | 'view'): void;
6
+ export declare function handleGetSprintArtifacts(ctx: HandlerContext, ws: WSContext, msg: WebSocketMessage, workingDir: string): void;
7
+ //# sourceMappingURL=plan-sprint-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-sprint-handlers.d.ts","sourceRoot":"","sources":["../../../../server/services/websocket/plan-sprint-handlers.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAkD9D,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EACzD,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,GAClD,IAAI,CAkCN;AAmBD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EACzD,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,GAClD,IAAI,CAyCN;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EACzD,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,GAAG,MAAM,GAClD,IAAI,CAmEN;AAED,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EACzD,UAAU,EAAE,MAAM,GACjB,IAAI,CAcN"}
@@ -0,0 +1,206 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { replaceFrontMatterField } from '../plan/front-matter.js';
6
+ import { defaultPmDir, getNextSprintId, parsePlanDirectory, parseSingleSprint, parseSprintArtifacts, resolvePmDir } from '../plan/parser.js';
7
+ import { denyIfViewOnly, resolvePlanPath } from './plan-helpers.js';
8
+ // ============================================================================
9
+ // Sprint lifecycle handlers (legacy — kept for backward compatibility)
10
+ // ============================================================================
11
+ function buildSprintMarkdown(id, title, goal, start, end, issueRefs) {
12
+ const issuesYaml = issueRefs.length > 0
13
+ ? `\n${issueRefs.map(p => ` - ${p}`).join('\n')}`
14
+ : ' []';
15
+ return `---
16
+ id: ${id}
17
+ title: "${title.replace(/"/g, '\\"')}"
18
+ status: planned
19
+ start: "${start}"
20
+ end: "${end}"
21
+ goal: "${goal.replace(/"/g, '\\"')}"
22
+ capacity: null
23
+ committed: null
24
+ completed: null
25
+ completed_at: null
26
+ issues:${issuesYaml}
27
+ ---
28
+
29
+ # ${id}: ${title}
30
+
31
+ ## Sprint Goal
32
+ ${goal}
33
+
34
+ ## Issues
35
+ | Issue | Title | Points | Status |
36
+ |---|---|---|---|
37
+ `;
38
+ }
39
+ /** Assign issues to a sprint by updating their front matter sprint field. */
40
+ function assignIssuesToSprint(workingDir, issues, issueIds, sprintPath) {
41
+ for (const issueId of issueIds) {
42
+ const issue = issues.find(i => i.id === issueId);
43
+ if (!issue)
44
+ continue;
45
+ const fullPath = resolvePlanPath(workingDir, issue.path);
46
+ if (!fullPath || !existsSync(fullPath))
47
+ continue;
48
+ const content = replaceFrontMatterField(readFileSync(fullPath, 'utf-8'), 'sprint', sprintPath);
49
+ writeFileSync(fullPath, content, 'utf-8');
50
+ }
51
+ }
52
+ export function handleCreateSprint(ctx, ws, msg, workingDir, permission) {
53
+ if (denyIfViewOnly(ctx, ws, permission))
54
+ return;
55
+ const { title, goal = '', start = '', end = '', issueIds = [] } = msg.data || {};
56
+ if (!title) {
57
+ ctx.send(ws, { type: 'planError', data: { error: 'Sprint title required' } });
58
+ return;
59
+ }
60
+ const pmDir = resolvePmDir(workingDir) ?? defaultPmDir(workingDir);
61
+ const sprintsDir = join(pmDir, 'sprints');
62
+ if (!existsSync(sprintsDir))
63
+ mkdirSync(sprintsDir, { recursive: true });
64
+ const fullState = parsePlanDirectory(workingDir);
65
+ const id = fullState ? getNextSprintId(fullState.sprints) : 'SPRINT-001';
66
+ const issueRefs = issueIds.map((issueId) => {
67
+ const issue = fullState?.issues.find(i => i.id === issueId);
68
+ return issue ? issue.path : `backlog/${issueId}.md`;
69
+ });
70
+ writeFileSync(join(sprintsDir, `${id}.md`), buildSprintMarkdown(id, title, goal, start, end, issueRefs), 'utf-8');
71
+ const sandboxDir = join(sprintsDir, id);
72
+ mkdirSync(join(sandboxDir, 'out'), { recursive: true });
73
+ mkdirSync(join(sandboxDir, 'reviews'), { recursive: true });
74
+ writeFileSync(join(sandboxDir, 'progress.md'), `# ${id}: ${title} — Progress Log\n`, 'utf-8');
75
+ if (issueRefs.length > 0 && fullState) {
76
+ assignIssuesToSprint(workingDir, fullState.issues, issueIds, `sprints/${id}.md`);
77
+ }
78
+ const sprint = parseSingleSprint(workingDir, `sprints/${id}.md`);
79
+ ctx.broadcastToAll({ type: 'planSprintCreated', data: sprint });
80
+ }
81
+ /** Promote sprint issues from 'backlog' to 'todo' status. */
82
+ function promoteSprintIssues(pmDir, sprint, allIssues) {
83
+ for (const issueSummary of sprint.issues) {
84
+ const issue = allIssues.find(i => i.id === issueSummary.id || i.path === issueSummary.path);
85
+ if (!issue || issue.status !== 'backlog')
86
+ continue;
87
+ const issuePath = join(pmDir, issue.path);
88
+ if (!existsSync(issuePath))
89
+ continue;
90
+ writeFileSync(issuePath, replaceFrontMatterField(readFileSync(issuePath, 'utf-8'), 'status', 'todo'), 'utf-8');
91
+ }
92
+ }
93
+ /** Update a file's front matter field if the file exists. */
94
+ function updateFileField(filePath, field, value) {
95
+ if (!existsSync(filePath))
96
+ return;
97
+ writeFileSync(filePath, replaceFrontMatterField(readFileSync(filePath, 'utf-8'), field, value), 'utf-8');
98
+ }
99
+ export function handleActivateSprint(ctx, ws, msg, workingDir, permission) {
100
+ if (denyIfViewOnly(ctx, ws, permission))
101
+ return;
102
+ const sprintId = msg.data?.sprintId;
103
+ if (!sprintId) {
104
+ ctx.send(ws, { type: 'planError', data: { error: 'Sprint ID required' } });
105
+ return;
106
+ }
107
+ const fullState = parsePlanDirectory(workingDir);
108
+ if (!fullState) {
109
+ ctx.send(ws, { type: 'planError', data: { error: 'No project found' } });
110
+ return;
111
+ }
112
+ const currentActive = fullState.sprints.find(s => s.status === 'active');
113
+ if (currentActive && currentActive.id !== sprintId) {
114
+ ctx.send(ws, { type: 'planError', data: { error: `Sprint ${currentActive.id} is already active. Complete it first.` } });
115
+ return;
116
+ }
117
+ const sprint = fullState.sprints.find(s => s.id === sprintId);
118
+ if (!sprint) {
119
+ ctx.send(ws, { type: 'planError', data: { error: `Sprint not found: ${sprintId}` } });
120
+ return;
121
+ }
122
+ const pmDir = resolvePmDir(workingDir);
123
+ if (!pmDir)
124
+ return;
125
+ updateFileField(join(pmDir, sprint.path), 'status', 'active');
126
+ updateFileField(join(pmDir, 'STATE.md'), 'current_sprint', `"${sprint.path}"`);
127
+ promoteSprintIssues(pmDir, sprint, fullState.issues);
128
+ const updatedSprint = parseSingleSprint(workingDir, sprint.path);
129
+ ctx.broadcastToAll({ type: 'planSprintUpdated', data: updatedSprint });
130
+ const updatedState = parsePlanDirectory(workingDir);
131
+ if (updatedState) {
132
+ ctx.broadcastToAll({ type: 'planStateUpdated', data: updatedState });
133
+ }
134
+ }
135
+ export function handleCompleteSprint(ctx, ws, msg, workingDir, permission) {
136
+ if (denyIfViewOnly(ctx, ws, permission))
137
+ return;
138
+ const sprintId = msg.data?.sprintId;
139
+ if (!sprintId) {
140
+ ctx.send(ws, { type: 'planError', data: { error: 'Sprint ID required' } });
141
+ return;
142
+ }
143
+ const fullState = parsePlanDirectory(workingDir);
144
+ if (!fullState) {
145
+ ctx.send(ws, { type: 'planError', data: { error: 'No project found' } });
146
+ return;
147
+ }
148
+ const sprint = fullState.sprints.find(s => s.id === sprintId);
149
+ if (!sprint) {
150
+ ctx.send(ws, { type: 'planError', data: { error: `Sprint not found: ${sprintId}` } });
151
+ return;
152
+ }
153
+ const pmDir = resolvePmDir(workingDir);
154
+ if (!pmDir)
155
+ return;
156
+ const now = new Date().toISOString();
157
+ const sprintIssues = fullState.issues.filter(i => i.sprint === sprint.path);
158
+ const completedIssues = sprintIssues.filter(i => i.status === 'done').length;
159
+ const failedIssues = sprintIssues.filter(i => i.status !== 'done' && i.status !== 'cancelled').length;
160
+ const sprintPath = join(pmDir, sprint.path);
161
+ if (existsSync(sprintPath)) {
162
+ let content = readFileSync(sprintPath, 'utf-8');
163
+ content = replaceFrontMatterField(content, 'status', 'completed');
164
+ content = replaceFrontMatterField(content, 'completed_at', `"${now}"`);
165
+ content = replaceFrontMatterField(content, 'completed', String(completedIssues));
166
+ if (!content.includes('execution_summary:')) {
167
+ const summaryYaml = [
168
+ 'execution_summary:',
169
+ ` total_issues: ${sprintIssues.length}`,
170
+ ` completed_issues: ${completedIssues}`,
171
+ ` failed_issues: ${failedIssues}`,
172
+ ].join('\n');
173
+ const fmClose = content.indexOf('\n---', content.indexOf('---') + 3);
174
+ if (fmClose !== -1) {
175
+ content = `${content.slice(0, fmClose)}\n${summaryYaml}${content.slice(fmClose)}`;
176
+ }
177
+ }
178
+ writeFileSync(sprintPath, content, 'utf-8');
179
+ }
180
+ const statePath = join(pmDir, 'STATE.md');
181
+ if (existsSync(statePath)) {
182
+ let stateContent = readFileSync(statePath, 'utf-8');
183
+ stateContent = replaceFrontMatterField(stateContent, 'current_sprint', 'null');
184
+ writeFileSync(statePath, stateContent, 'utf-8');
185
+ }
186
+ const updatedSprint = parseSingleSprint(workingDir, sprint.path);
187
+ ctx.broadcastToAll({ type: 'planSprintCompleted', data: updatedSprint });
188
+ const updatedState = parsePlanDirectory(workingDir);
189
+ if (updatedState) {
190
+ ctx.broadcastToAll({ type: 'planStateUpdated', data: updatedState });
191
+ }
192
+ }
193
+ export function handleGetSprintArtifacts(ctx, ws, msg, workingDir) {
194
+ const sprintId = msg.data?.sprintId;
195
+ if (!sprintId) {
196
+ ctx.send(ws, { type: 'planError', data: { error: 'Sprint ID required' } });
197
+ return;
198
+ }
199
+ const artifacts = parseSprintArtifacts(workingDir, sprintId);
200
+ if (!artifacts) {
201
+ ctx.send(ws, { type: 'planSprintArtifacts', data: { sprintId, progressLog: '', outputFiles: [], reviewResults: [] } });
202
+ return;
203
+ }
204
+ ctx.send(ws, { type: 'planSprintArtifacts', data: artifacts });
205
+ }
206
+ //# sourceMappingURL=plan-sprint-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-sprint-handlers.js","sourceRoot":"","sources":["../../../../server/services/websocket/plan-sprint-handlers.ts"],"names":[],"mappings":"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"}