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,98 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+
4
+ /**
5
+ * Types and interfaces for the Improvisation Session Manager.
6
+ */
7
+
8
+ import type { HeadlessRunner } from './headless/index.js';
9
+ import type { ExecutionCheckpoint } from './headless/types.js';
10
+
11
+ export interface ImprovisationOptions {
12
+ workingDir: string;
13
+ sessionId: string;
14
+ tokenBudgetThreshold: number;
15
+ maxSessions: number;
16
+ verbose: boolean;
17
+ noColor: boolean;
18
+ /** Claude model for main execution (e.g., 'opus', 'sonnet'). 'default' = no --model flag. */
19
+ model?: string;
20
+ }
21
+
22
+ // File attachment for multimodal prompts (images)
23
+ export interface FileAttachment {
24
+ fileName: string; // Display name (e.g., "screenshot.png")
25
+ filePath: string; // Full path on disk (for context)
26
+ content: string; // Base64 for images
27
+ isImage: boolean; // True for image files
28
+ mimeType?: string; // MIME type for images (e.g., "image/png")
29
+ }
30
+
31
+ export interface ToolUseRecord {
32
+ toolName: string;
33
+ toolId: string;
34
+ toolInput: Record<string, unknown>;
35
+ result?: string;
36
+ isError?: boolean;
37
+ duration?: number;
38
+ }
39
+
40
+ export interface MovementRecord {
41
+ id: string;
42
+ sequenceNumber: number;
43
+ userPrompt: string;
44
+ timestamp: string;
45
+ tokensUsed: number;
46
+ summary: string;
47
+ filesModified: string[];
48
+ assistantResponse?: string;
49
+ thinkingOutput?: string;
50
+ toolUseHistory?: ToolUseRecord[];
51
+ errorOutput?: string;
52
+ durationMs?: number;
53
+ retryLog?: RetryLogEntry[];
54
+ }
55
+
56
+ export interface SessionHistory {
57
+ sessionId: string;
58
+ startedAt: string;
59
+ lastActivityAt: string;
60
+ totalTokens: number;
61
+ movements: MovementRecord[];
62
+ claudeSessionId?: string;
63
+ }
64
+
65
+ /** Entry in the retry log for debugging recovery paths */
66
+ export interface RetryLogEntry {
67
+ retryNumber: number;
68
+ path: string;
69
+ reason: string;
70
+ timestamp: number;
71
+ durationMs?: number;
72
+ }
73
+
74
+ /** Mutable state for the retry loop in executePrompt */
75
+ export interface RetryLoopState {
76
+ currentPrompt: string;
77
+ retryNumber: number;
78
+ checkpointRef: { value: ExecutionCheckpoint | null };
79
+ contextRecoverySessionId: string | undefined;
80
+ freshRecoveryMode: boolean;
81
+ accumulatedToolResults: ToolUseRecord[];
82
+ contextLost: boolean;
83
+ lastWatchdogCheckpoint: ExecutionCheckpoint | null;
84
+ timedOutTools: Array<{ toolName: string; input: Record<string, unknown>; timeoutMs: number }>;
85
+ bestResult: HeadlessRunResult | null;
86
+ retryLog: RetryLogEntry[];
87
+ }
88
+
89
+ /** Type alias for HeadlessRunner execution result */
90
+ export type HeadlessRunResult = Awaited<ReturnType<HeadlessRunner['run']>>;
91
+
92
+ /** Score a run result for best-result tracking (higher = more productive) */
93
+ export function scoreRunResult(r: HeadlessRunResult): number {
94
+ const toolCount = r.toolUseHistory?.filter(t => t.result !== undefined && !t.isError).length ?? 0;
95
+ const responseLen = Math.min((r.assistantResponse?.length ?? 0) / 50, 100);
96
+ const hasThinking = r.thinkingOutput ? 20 : 0;
97
+ return toolCount * 10 + responseLen + hasThinking;
98
+ }
@@ -0,0 +1,370 @@
1
+ /**
2
+ * Prompt building and formatting utilities for improvisation sessions.
3
+ * Extracted from ImprovisationSessionManager for Single Responsibility.
4
+ *
5
+ * These are stateless formatting functions that take their inputs as parameters.
6
+ */
7
+
8
+ import type { ExecutionCheckpoint } from './headless/types.js';
9
+ import type { MovementRecord, ToolUseRecord } from './improvisation-session-manager.js';
10
+
11
+ // ============================================================================
12
+ // Formatting Utilities
13
+ // ============================================================================
14
+
15
+ /** Summarize a tool input for display in retry prompts */
16
+ export function summarizeToolInput(input: Record<string, unknown>): string {
17
+ if (input.url) return String(input.url).slice(0, 100);
18
+ if (input.query) return String(input.query).slice(0, 100);
19
+ if (input.command) return String(input.command).slice(0, 100);
20
+ if (input.prompt) return String(input.prompt).slice(0, 100);
21
+ return JSON.stringify(input).slice(0, 100);
22
+ }
23
+
24
+ /** Format a list of timed-out tools for retry prompts */
25
+ export function formatTimedOutTools(tools: Array<{ toolName: string; input: Record<string, unknown>; timeoutMs: number }>): string[] {
26
+ const lines: string[] = [];
27
+ lines.push('### Tools/resources that have timed out (DO NOT retry these):');
28
+ for (const t of tools) {
29
+ const inputSummary = summarizeToolInput(t.input);
30
+ lines.push(`- **${t.toolName}**(${inputSummary}) — timed out after ${Math.round(t.timeoutMs / 1000)}s`);
31
+ }
32
+ return lines;
33
+ }
34
+
35
+ /** Format completed checkpoint tools for retry prompts */
36
+ export function formatCompletedTools(tools: Array<{ toolName: string; input: Record<string, unknown>; result: string }>, maxLen = 2000): string[] {
37
+ const lines: string[] = [];
38
+ lines.push('### Results already obtained:');
39
+ for (const tool of tools) {
40
+ const inputSummary = summarizeToolInput(tool.input);
41
+ const preview = tool.result.length > maxLen ? `${tool.result.slice(0, maxLen)}...` : tool.result;
42
+ lines.push(`- **${tool.toolName}**(${inputSummary}): ${preview}`);
43
+ }
44
+ return lines;
45
+ }
46
+
47
+ /** Format in-progress tools for retry prompts */
48
+ export function formatInProgressTools(tools: Array<{ toolName: string; input: Record<string, unknown> }>): string[] {
49
+ const lines: string[] = [];
50
+ lines.push('### Tools that were still running (lost when process was killed):');
51
+ for (const tool of tools) {
52
+ const inputSummary = summarizeToolInput(tool.input);
53
+ lines.push(`- **${tool.toolName}**(${inputSummary}) — was in progress, may need re-running`);
54
+ }
55
+ return lines;
56
+ }
57
+
58
+ /** Format tool results from ToolUseRecord[] for recovery prompts */
59
+ export function formatToolResults(toolResults: ToolUseRecord[], maxLen = 3000): string[] {
60
+ const completed = toolResults.filter(t => t.result !== undefined && !t.isError);
61
+ if (completed.length === 0) return [];
62
+ const lines: string[] = [`### ${completed.length} preserved results from prior work:`, ''];
63
+ for (const tool of completed) {
64
+ const inputSummary = summarizeToolInput(tool.toolInput);
65
+ const preview = tool.result && tool.result.length > maxLen
66
+ ? `${tool.result.slice(0, maxLen)}...\n(truncated, ${tool.result.length} chars total)`
67
+ : tool.result || '';
68
+ lines.push(`**${tool.toolName}**(${inputSummary}):`);
69
+ lines.push(preview);
70
+ lines.push('');
71
+ }
72
+ return lines;
73
+ }
74
+
75
+ /** Format conversation history for recovery prompts */
76
+ export function formatConversationHistory(movements: MovementRecord[], maxMovements = 5): string[] {
77
+ const recent = movements.slice(-maxMovements);
78
+ if (recent.length === 0) return [];
79
+ const lines: string[] = ['### Conversation so far:'];
80
+ for (const movement of recent) {
81
+ const promptText = movement.userPrompt.length > 300 ? `${movement.userPrompt.slice(0, 300)}...` : movement.userPrompt;
82
+ lines.push(`**User (prompt ${movement.sequenceNumber}):** ${promptText}`);
83
+ if (movement.assistantResponse) {
84
+ const response = movement.assistantResponse.length > 1000
85
+ ? `${movement.assistantResponse.slice(0, 1000)}...\n(truncated, ${movement.assistantResponse.length} chars)`
86
+ : movement.assistantResponse;
87
+ lines.push(`**Your response:** ${response}`);
88
+ }
89
+ lines.push('');
90
+ }
91
+ return lines;
92
+ }
93
+
94
+ // ============================================================================
95
+ // Prompt Builders
96
+ // ============================================================================
97
+
98
+ /** Build historical context from prior movements (for resumed sessions or first prompt with history) */
99
+ export function buildHistoricalContext(movements: MovementRecord[]): string {
100
+ if (movements.length === 0) {
101
+ return '';
102
+ }
103
+
104
+ const contextParts: string[] = [
105
+ '--- CONVERSATION HISTORY (for context, do not repeat these responses) ---',
106
+ ''
107
+ ];
108
+
109
+ for (const movement of movements) {
110
+ contextParts.push(`[User Prompt ${movement.sequenceNumber}]:`);
111
+ contextParts.push(movement.userPrompt);
112
+ contextParts.push('');
113
+
114
+ if (movement.assistantResponse) {
115
+ contextParts.push(`[Your Response ${movement.sequenceNumber}]:`);
116
+ const response = movement.assistantResponse.length > 2000
117
+ ? `${movement.assistantResponse.slice(0, 2000)}\n... (response truncated for context)`
118
+ : movement.assistantResponse;
119
+ contextParts.push(response);
120
+ contextParts.push('');
121
+ }
122
+
123
+ if (movement.toolUseHistory && movement.toolUseHistory.length > 0) {
124
+ contextParts.push(`[Tools Used in Prompt ${movement.sequenceNumber}]:`);
125
+ for (const tool of movement.toolUseHistory) {
126
+ contextParts.push(`- ${tool.toolName}`);
127
+ }
128
+ contextParts.push('');
129
+ }
130
+ }
131
+
132
+ contextParts.push('--- END OF CONVERSATION HISTORY ---');
133
+ contextParts.push('');
134
+ contextParts.push('Continue the conversation from where we left off. The user is now asking:');
135
+ contextParts.push('');
136
+
137
+ return contextParts.join('\n');
138
+ }
139
+
140
+ /**
141
+ * Build a retry prompt from a tool timeout checkpoint.
142
+ * Injects completed tool results and instructs Claude to skip the failed resource.
143
+ */
144
+ export function buildRetryPrompt(
145
+ checkpoint: ExecutionCheckpoint,
146
+ originalPrompt: string,
147
+ allTimedOut?: Array<{ toolName: string; input: Record<string, unknown>; timeoutMs: number }>,
148
+ ): string {
149
+ const urlSuffix = checkpoint.hungTool.url ? ` while fetching: ${checkpoint.hungTool.url}` : '';
150
+ const parts: string[] = [
151
+ '## AUTOMATIC RETRY -- Previous Execution Interrupted',
152
+ '',
153
+ `The previous execution was interrupted because ${checkpoint.hungTool.toolName} timed out after ${Math.round(checkpoint.hungTool.timeoutMs / 1000)}s${urlSuffix}.`,
154
+ '',
155
+ ];
156
+
157
+ if (allTimedOut && allTimedOut.length > 0) {
158
+ parts.push(...formatTimedOutTools(allTimedOut), '');
159
+ } else {
160
+ parts.push('This URL/resource is unreachable. DO NOT retry the same URL or query.', '');
161
+ }
162
+
163
+ if (checkpoint.completedTools.length > 0) {
164
+ parts.push(...formatCompletedTools(checkpoint.completedTools), '');
165
+ }
166
+
167
+ if (checkpoint.inProgressTools && checkpoint.inProgressTools.length > 0) {
168
+ parts.push(...formatInProgressTools(checkpoint.inProgressTools), '');
169
+ }
170
+
171
+ if (checkpoint.assistantText) {
172
+ const preview = checkpoint.assistantText.length > 8000
173
+ ? `${checkpoint.assistantText.slice(0, 8000)}...\n(truncated — full response was ${checkpoint.assistantText.length} chars)`
174
+ : checkpoint.assistantText;
175
+ parts.push('### Your response before interruption:', preview, '');
176
+ }
177
+
178
+ parts.push('### Original task (continue from where you left off):');
179
+ parts.push(originalPrompt);
180
+ parts.push('');
181
+ parts.push('INSTRUCTIONS:');
182
+ parts.push('1. Use the results above -- do not re-fetch content you already have');
183
+ parts.push('2. Find ALTERNATIVE sources for the content that timed out (different URL, different approach)');
184
+ parts.push('3. Re-run any in-progress tools that were lost (listed above) if their results are needed');
185
+ parts.push('4. If no alternative exists, proceed with the results you have and note what was unavailable');
186
+
187
+ return parts.join('\n');
188
+ }
189
+
190
+ /**
191
+ * Build a short retry prompt for --resume sessions.
192
+ */
193
+ export function buildResumeRetryPrompt(
194
+ checkpoint: ExecutionCheckpoint,
195
+ allTimedOut?: Array<{ toolName: string; input: Record<string, unknown>; timeoutMs: number }>,
196
+ ): string {
197
+ const parts: string[] = [];
198
+
199
+ parts.push(
200
+ `Your previous ${checkpoint.hungTool.toolName} call timed out after ${Math.round(checkpoint.hungTool.timeoutMs / 1000)}s${checkpoint.hungTool.url ? ` fetching: ${checkpoint.hungTool.url}` : ''}.`
201
+ );
202
+
203
+ if (allTimedOut && allTimedOut.length > 1) {
204
+ parts.push('');
205
+ parts.push('All timed-out tools/resources (DO NOT retry any of these):');
206
+ for (const t of allTimedOut) {
207
+ const inputSummary = summarizeToolInput(t.input);
208
+ parts.push(`- ${t.toolName}(${inputSummary})`);
209
+ }
210
+ } else {
211
+ parts.push('This URL/resource is unreachable. DO NOT retry the same URL or query.');
212
+ }
213
+ parts.push('Continue your task — find an alternative source or proceed with the results you already have.');
214
+
215
+ return parts.join('\n');
216
+ }
217
+
218
+ /** Build a recovery prompt for --resume after context loss. */
219
+ export function buildContextRecoveryPrompt(originalPrompt: string): string {
220
+ const parts: string[] = [];
221
+
222
+ parts.push('Your previous response indicated you lost context due to tool timeouts, but your full conversation history is preserved — including all successful tool results.');
223
+ parts.push('');
224
+ parts.push('Review your conversation history above. You already have results from many successful tool calls. Use those results to continue the task.');
225
+ parts.push('');
226
+ parts.push('Original task:');
227
+ parts.push(originalPrompt);
228
+ parts.push('');
229
+ parts.push('INSTRUCTIONS:');
230
+ parts.push('1. Review your conversation history — all your previous tool results are still available');
231
+ parts.push('2. Continue from where you left off using the results you already gathered');
232
+ parts.push('3. If specific tool calls timed out, skip those and work with what you have');
233
+ parts.push('4. Do NOT start over — build on the work already done');
234
+ parts.push('5. Do NOT spawn Task subagents for work that previously timed out — do it inline instead');
235
+ parts.push('6. Prefer multiple small, focused tool calls over single large ones to avoid further timeouts');
236
+
237
+ return parts.join('\n');
238
+ }
239
+
240
+ /** Build a recovery prompt for a fresh session after repeated context loss. */
241
+ export function buildFreshRecoveryPrompt(
242
+ originalPrompt: string,
243
+ toolResults: ToolUseRecord[],
244
+ timedOutTools?: Array<{ toolName: string; input: Record<string, unknown>; timeoutMs: number }>,
245
+ ): string {
246
+ const parts: string[] = [
247
+ '## CONTINUING LONG-RUNNING TASK',
248
+ '',
249
+ 'The previous execution encountered tool timeouts and lost context.',
250
+ 'Below are all results gathered before the interruption. Continue the task using these results.',
251
+ '',
252
+ ];
253
+
254
+ if (timedOutTools && timedOutTools.length > 0) {
255
+ parts.push(...formatTimedOutTools(timedOutTools), '');
256
+ }
257
+
258
+ parts.push(...formatToolResults(toolResults));
259
+
260
+ parts.push('### Original task:');
261
+ parts.push(originalPrompt);
262
+ parts.push('');
263
+ parts.push('INSTRUCTIONS:');
264
+ parts.push('1. Use the preserved results above — do NOT re-fetch data you already have');
265
+ parts.push('2. Continue the task from where it was interrupted');
266
+ parts.push('3. If you need additional data, fetch it (but try alternative sources if the original timed out)');
267
+ parts.push('4. Complete the original task fully');
268
+ parts.push('5. Do NOT spawn Task subagents for work that previously timed out — do it inline instead');
269
+ parts.push('6. Prefer multiple small, focused tool calls over single large ones to avoid further timeouts');
270
+
271
+ return parts.join('\n');
272
+ }
273
+
274
+ /** Build a recovery prompt for inter-movement context loss. */
275
+ export function buildInterMovementRecoveryPrompt(
276
+ originalPrompt: string,
277
+ toolResults: ToolUseRecord[],
278
+ movements: MovementRecord[],
279
+ ): string {
280
+ const parts: string[] = [
281
+ '## SESSION RECOVERY — Prior Session Expired',
282
+ '',
283
+ 'Your previous session expired between prompts. Below is a summary of the conversation so far and all preserved tool results.',
284
+ '',
285
+ ];
286
+
287
+ parts.push(...formatConversationHistory(movements));
288
+ parts.push(...formatToolResults(toolResults));
289
+
290
+ parts.push('### Current user prompt:');
291
+ parts.push(originalPrompt);
292
+ parts.push('');
293
+ parts.push('INSTRUCTIONS:');
294
+ parts.push('1. Use the preserved results above — do NOT re-fetch data you already have');
295
+ parts.push('2. Continue the conversation naturally based on the history above');
296
+ parts.push('3. If you need additional data, fetch it with small focused tool calls');
297
+ parts.push('4. Do NOT spawn Task subagents — do work inline to avoid further timeouts');
298
+ parts.push('5. Prefer multiple small, focused tool calls over single large ones');
299
+
300
+ return parts.join('\n');
301
+ }
302
+
303
+ /** Build a recovery prompt after signal crash */
304
+ export function buildSignalCrashRecoveryPrompt(
305
+ originalPrompt: string,
306
+ isResume: boolean,
307
+ toolResults?: ToolUseRecord[],
308
+ ): string {
309
+ const parts: string[] = [];
310
+
311
+ if (isResume) {
312
+ parts.push('Your previous execution was interrupted by a system signal (the process was killed externally).');
313
+ parts.push('Your full conversation history is preserved — including all successful tool results.');
314
+ parts.push('');
315
+ parts.push('Review your conversation history above and continue from where you left off.');
316
+ } else {
317
+ parts.push('## AUTOMATIC RETRY — Previous Execution Interrupted');
318
+ parts.push('');
319
+ parts.push('The previous execution was interrupted by a system signal (process killed).');
320
+ if (toolResults && toolResults.length > 0) {
321
+ parts.push(`${toolResults.length} tool results were preserved from prior work.`);
322
+ parts.push('');
323
+ parts.push('### Preserved results:');
324
+ for (const t of toolResults.slice(-20)) {
325
+ const inputSummary = JSON.stringify(t.toolInput).slice(0, 120);
326
+ const resultPreview = (t.result ?? '').slice(0, 200);
327
+ parts.push(`- **${t.toolName}**(${inputSummary}): ${resultPreview}`);
328
+ }
329
+ }
330
+ }
331
+
332
+ parts.push('');
333
+ parts.push('### Original task:');
334
+ parts.push(originalPrompt);
335
+ parts.push('');
336
+ parts.push('INSTRUCTIONS:');
337
+ parts.push('1. Use the results above -- do not re-fetch content you already have');
338
+ parts.push('2. Continue from where you left off');
339
+ parts.push('3. Prefer multiple small, focused tool calls over single large ones');
340
+ parts.push('4. Do NOT spawn Task subagents — do work inline to avoid further interruptions');
341
+
342
+ return parts.join('\n');
343
+ }
344
+
345
+ /**
346
+ * Extract tool results from movements.
347
+ * Used for recovery to provide context from prior work.
348
+ */
349
+ export function extractHistoricalToolResults(movements: MovementRecord[], maxMovements = 3): ToolUseRecord[] {
350
+ const results: ToolUseRecord[] = [];
351
+ const recentMovements = movements.slice(-maxMovements);
352
+
353
+ for (const movement of recentMovements) {
354
+ if (!movement.toolUseHistory) continue;
355
+ for (const tool of movement.toolUseHistory) {
356
+ if (tool.result !== undefined && !tool.isError) {
357
+ results.push({
358
+ toolName: tool.toolName,
359
+ toolId: tool.toolId,
360
+ toolInput: tool.toolInput,
361
+ result: tool.result,
362
+ isError: tool.isError,
363
+ duration: tool.duration,
364
+ });
365
+ }
366
+ }
367
+ }
368
+
369
+ return results;
370
+ }