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
package/bin/mstro.js CHANGED
@@ -23,38 +23,16 @@ import { homedir } from 'node:os';
23
23
  import { dirname, join, resolve } from 'node:path';
24
24
  import { createInterface } from 'node:readline';
25
25
  import { fileURLToPath } from 'node:url';
26
- import semverGt from 'semver/functions/gt.js';
27
- import updateNotifier from 'update-notifier';
28
26
 
29
27
  const __filename = fileURLToPath(import.meta.url);
30
28
  const __dirname = dirname(__filename);
31
29
  const CLIENT_ROOT = resolve(__dirname, '..');
32
30
 
33
- // Read package.json for update-notifier
34
31
  const pkg = JSON.parse(readFileSync(join(CLIENT_ROOT, 'package.json'), 'utf-8'));
35
32
 
36
- // Check for updates (runs async in background, notifies on next run)
37
- // update-notifier initializes lastUpdateCheck to Date.now(), which means the
38
- // first check won't happen until 24h after install. We detect first-run by
39
- // checking if the configstore has never stored an update result, and if so
40
- // reset the timestamp to force an immediate background check.
41
- const notifier = updateNotifier({
42
- pkg,
43
- updateCheckInterval: 1000 * 60 * 60 * 24 // Check daily
44
- });
45
- try {
46
- if (notifier.config && !notifier.config.has('update') && !notifier.update) {
47
- const lastCheck = notifier.config.get('lastUpdateCheck');
48
- // If lastUpdateCheck was just set (within the last 30s), this is a fresh
49
- // configstore — reset it to 0 so the library spawns a check immediately.
50
- if (lastCheck && (Date.now() - lastCheck) < 30_000) {
51
- notifier.config.set('lastUpdateCheck', 0);
52
- notifier.check();
53
- }
54
- }
55
- } catch {
56
- // Non-critical — don't let update check logic crash the CLI
57
- }
33
+ // Self-update: cache file for registry check results
34
+ const UPDATE_CHECK_FILE = join(homedir(), '.mstro', 'update-check.json');
35
+ const UPDATE_CHECK_INTERVAL = 1000 * 60 * 60; // Re-check hourly
58
36
 
59
37
  // Capture the user's original working directory before any cwd changes
60
38
  const USER_CWD = process.cwd();
@@ -403,32 +381,135 @@ function parseServerUrl(args) {
403
381
  return null;
404
382
  }
405
383
 
384
+ /**
385
+ * Compare two semver strings (x.y.z). Returns 1 if a > b, -1 if a < b, 0 if equal.
386
+ */
387
+ function compareVersions(a, b) {
388
+ const pa = a.split('.').map(Number);
389
+ const pb = b.split('.').map(Number);
390
+ for (let i = 0; i < 3; i++) {
391
+ if ((pa[i] || 0) > (pb[i] || 0)) return 1;
392
+ if ((pa[i] || 0) < (pb[i] || 0)) return -1;
393
+ }
394
+ return 0;
395
+ }
396
+
397
+ /**
398
+ * Read cached update check result from ~/.mstro/update-check.json
399
+ */
400
+ function readUpdateCache() {
401
+ try {
402
+ if (!existsSync(UPDATE_CHECK_FILE)) return null;
403
+ return JSON.parse(readFileSync(UPDATE_CHECK_FILE, 'utf-8'));
404
+ } catch {
405
+ return null;
406
+ }
407
+ }
408
+
409
+ /**
410
+ * Write the update check cache.
411
+ */
412
+ function writeUpdateCache(latest) {
413
+ try {
414
+ const dir = dirname(UPDATE_CHECK_FILE);
415
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
416
+ writeFileSync(UPDATE_CHECK_FILE, JSON.stringify({ latest, checkedAt: Date.now() }));
417
+ } catch {
418
+ // Non-fatal
419
+ }
420
+ }
421
+
422
+ /**
423
+ * Fetch the latest published version from the npm registry inline.
424
+ * Returns the version string, or null on failure/timeout.
425
+ */
426
+ async function fetchLatestVersion(timeoutMs = 3000) {
427
+ try {
428
+ const res = await fetch(`https://registry.npmjs.org/${pkg.name}/latest`, {
429
+ signal: AbortSignal.timeout(timeoutMs),
430
+ });
431
+ if (!res.ok) return null;
432
+ const { version } = await res.json();
433
+ if (version) writeUpdateCache(version);
434
+ return version || null;
435
+ } catch {
436
+ return null;
437
+ }
438
+ }
439
+
440
+ /**
441
+ * Determine the update type label from two semver strings.
442
+ */
443
+ function updateType(current, latest) {
444
+ const c = current.split('.').map(Number);
445
+ const l = latest.split('.').map(Number);
446
+ if (l[0] > c[0]) return 'major';
447
+ if (l[1] > c[1]) return 'minor';
448
+ return 'patch';
449
+ }
450
+
451
+ /**
452
+ * Resolve the latest available version, using cache when fresh.
453
+ */
454
+ async function resolveLatestVersion() {
455
+ const cache = readUpdateCache();
456
+
457
+ if (cache?.latest && (Date.now() - cache.checkedAt) < UPDATE_CHECK_INTERVAL) {
458
+ return cache.latest;
459
+ }
460
+
461
+ // Cache is stale or missing — check the registry inline
462
+ const fetched = await fetchLatestVersion(3000);
463
+ if (fetched) return fetched;
464
+
465
+ // Network failed — fall back to stale cache
466
+ return cache?.latest || null;
467
+ }
468
+
469
+ /**
470
+ * Install a specific version globally via npm.
471
+ * Returns { ok, stderr }.
472
+ */
473
+ function installGlobalVersion(version) {
474
+ const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
475
+ return new Promise((resolve) => {
476
+ const child = spawn(npmCmd, ['install', '-g', `${pkg.name}@${version}`], {
477
+ stdio: ['ignore', 'ignore', 'pipe'],
478
+ });
479
+ let stderr = '';
480
+ child.stderr.on('data', (d) => { stderr += d; });
481
+ child.on('error', () => resolve({ ok: false, stderr: '' }));
482
+ child.on('exit', (code) => resolve({ ok: code === 0, stderr }));
483
+ });
484
+ }
485
+
406
486
  /**
407
487
  * Auto-update if a new version is available.
408
- * Installs the update globally and re-execs mstro with the same arguments.
488
+ * Uses a local cache (refreshed hourly) so most startups add zero latency.
489
+ * When the cache is stale or missing, does an inline registry fetch (≤3 s).
490
+ * If a newer version exists, installs it globally and re-execs.
409
491
  * Returns true if the process was re-spawned (caller should return).
410
492
  */
411
493
  async function autoUpdate() {
412
494
  try {
413
- if (!notifier.update || !semverGt(notifier.update.latest, notifier.update.current)) {
495
+ const latest = await resolveLatestVersion();
496
+
497
+ if (!latest || compareVersions(latest, pkg.version) <= 0) {
414
498
  return false;
415
499
  }
416
500
 
417
- const { current, latest, type } = notifier.update;
501
+ const current = pkg.version;
502
+ const type = updateType(current, latest);
418
503
  log(`\n Updating mstro: ${colors.dim}${current}${colors.reset} → ${colors.green}${latest}${colors.reset} ${colors.dim}(${type})${colors.reset}`);
419
504
 
420
- const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
505
+ const installResult = await installGlobalVersion(latest);
421
506
 
422
- const success = await new Promise((resolve) => {
423
- const child = spawn(npmCmd, ['install', '-g', pkg.name], {
424
- stdio: ['ignore', 'ignore', 'pipe'],
425
- });
426
- child.on('error', () => resolve(false));
427
- child.on('exit', (code) => resolve(code === 0));
428
- });
429
-
430
- if (!success) {
507
+ if (!installResult.ok) {
431
508
  log(` Update failed — continuing with v${current}`, colors.yellow);
509
+ if (installResult.stderr) {
510
+ const reason = installResult.stderr.split('\n').find(l => l.trim()) || '';
511
+ if (reason) log(` ${colors.dim}${reason.trim()}${colors.reset}`);
512
+ }
432
513
  log(` Run manually: ${colors.cyan}npm i -g ${pkg.name}${colors.reset}\n`);
433
514
  return false;
434
515
  }
@@ -441,7 +522,6 @@ async function autoUpdate() {
441
522
  env: { ...process.env, MSTRO_SKIP_UPDATE_CHECK: '1' },
442
523
  });
443
524
 
444
- // Parent ignores SIGINT — child handles it via shared terminal
445
525
  process.on('SIGINT', () => {});
446
526
  process.on('SIGTERM', () => child.kill('SIGTERM'));
447
527
 
@@ -452,7 +532,6 @@ async function autoUpdate() {
452
532
 
453
533
  return true;
454
534
  } catch {
455
- // Don't let update logic crash the CLI
456
535
  return false;
457
536
  }
458
537
  }
@@ -0,0 +1,11 @@
1
+ import { type ChildProcess } from 'node:child_process';
2
+ import type { StreamHandlerContext } from './claude-invoker-stream.js';
3
+ import type { ExecutionResult, ResolvedHeadlessConfig } from './types.js';
4
+ export declare function handleSpawnError(error: NodeJS.ErrnoException, config: ResolvedHeadlessConfig, reject: (reason: Error) => void): void;
5
+ export declare function buildClaudeArgs(config: ResolvedHeadlessConfig, prompt: string, hasImageAttachments: boolean, useStreamJson: boolean, mcpConfigPath: string | null): string[];
6
+ /** Spawn the Claude CLI process and register it */
7
+ export declare function spawnAndRegister(config: ResolvedHeadlessConfig, prompt: string, hasImageAttachments: boolean, useStreamJson: boolean, runningProcesses: Map<number, ChildProcess>, perfStart: number): ChildProcess;
8
+ export declare function buildCloseResult(ctx: StreamHandlerContext, stdout: string, stderr: string, code: number | null, signal: NodeJS.Signals | null, sessionCapture: {
9
+ claudeSessionId?: string;
10
+ }): ExecutionResult;
11
+ //# sourceMappingURL=claude-invoker-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-invoker-process.d.ts","sourceRoot":"","sources":["../../../../server/cli/headless/claude-invoker-process.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,oBAAoB,CAAC;AAE9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAKvE,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AA0B1E,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,CAAC,cAAc,EAC5B,MAAM,EAAE,sBAAsB,EAC9B,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,IAAI,GAC9B,IAAI,CAYN;AAID,wBAAgB,eAAe,CAC7B,MAAM,EAAE,sBAAsB,EAC9B,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,OAAO,EAC5B,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,MAAM,EAAE,CAwCV;AAqBD,mDAAmD;AACnD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,sBAAsB,EAC9B,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,OAAO,EAC5B,aAAa,EAAE,OAAO,EACtB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAC3C,SAAS,EAAE,MAAM,GAChB,YAAY,CAyCd;AAID,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,oBAAoB,EACzB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,EAC7B,cAAc,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,eAAe,CAoBjB"}
@@ -0,0 +1,140 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ import { spawn } from 'node:child_process';
4
+ import { sanitizeEnvForSandbox } from '../../services/sandbox-utils.js';
5
+ import { flushNativeTimeoutBuffers, verboseLog } from './claude-invoker-stream.js';
6
+ import { herror } from './headless-logger.js';
7
+ import { generateMcpConfig } from './mcp-config.js';
8
+ import { buildMultimodalMessage } from './prompt-utils.js';
9
+ // ========== Signal Helpers ==========
10
+ /** Map a Node.js signal name to its numeric value for exit code computation */
11
+ function signalToNumber(signal) {
12
+ const map = {
13
+ SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGABRT: 6,
14
+ SIGKILL: 9, SIGTERM: 15, SIGUSR1: 10, SIGUSR2: 12,
15
+ };
16
+ return map[signal];
17
+ }
18
+ // ========== Error Handling ==========
19
+ const SPAWN_ERROR_MAP = {
20
+ ENOENT: {
21
+ code: 'CLAUDE_NOT_INSTALLED',
22
+ message: 'Claude Code is not installed or not in PATH. Please install Claude Code: npm install -g @anthropic-ai/claude-code'
23
+ },
24
+ EACCES: {
25
+ code: 'PERMISSION_DENIED',
26
+ message: 'Permission denied when running Claude Code. Please check file permissions.'
27
+ }
28
+ };
29
+ export function handleSpawnError(error, config, reject) {
30
+ const mapped = error.code ? SPAWN_ERROR_MAP[error.code] : undefined;
31
+ if (!mapped) {
32
+ reject(error);
33
+ return;
34
+ }
35
+ const formatted = `[[MSTRO_ERROR:${mapped.code}]] ${mapped.message}`;
36
+ if (config.outputCallback) {
37
+ config.outputCallback(`\n${formatted}\n`);
38
+ }
39
+ reject(new Error(formatted));
40
+ }
41
+ // ========== Argument Building ==========
42
+ export function buildClaudeArgs(config, prompt, hasImageAttachments, useStreamJson, mcpConfigPath) {
43
+ const args = ['--print'];
44
+ if (config.model && config.model !== 'default') {
45
+ args.push('--model', config.model);
46
+ }
47
+ if (useStreamJson) {
48
+ args.push('--output-format', 'stream-json', '--include-partial-messages', '--verbose');
49
+ }
50
+ if (hasImageAttachments) {
51
+ args.push('--input-format', 'stream-json');
52
+ }
53
+ if (config.claudeSessionId) {
54
+ args.push('--resume', config.claudeSessionId);
55
+ }
56
+ else if (config.continueSession) {
57
+ args.push('--continue');
58
+ }
59
+ if (config.disallowedTools && config.disallowedTools.length > 0) {
60
+ args.push('--disallowedTools', config.disallowedTools.join(','));
61
+ }
62
+ if (mcpConfigPath) {
63
+ args.push('--mcp-config', mcpConfigPath);
64
+ args.push('--permission-prompt-tool', 'mcp__mstro-bouncer__approval_prompt');
65
+ }
66
+ else {
67
+ args.push('--permission-mode', 'acceptEdits');
68
+ }
69
+ // Reduce Edit-without-Read errors by reminding the model
70
+ args.push('--append-system-prompt', 'IMPORTANT: Always use the Read tool to read a file before using Edit or Write on it. Never edit a file you have not read in this session.');
71
+ if (!hasImageAttachments) {
72
+ args.push(prompt);
73
+ }
74
+ return args;
75
+ }
76
+ /** Write image attachments to the Claude process stdin as stream-json */
77
+ function writeImageAttachmentsToStdin(claudeProcess, prompt, config) {
78
+ claudeProcess.stdin.on('error', (err) => {
79
+ if (config.verbose) {
80
+ herror('[STDIN] Write error:', err.message);
81
+ }
82
+ config.outputCallback?.(`\n[[MSTRO_ERROR:STDIN_WRITE_FAILED]] Failed to send image data to Claude: ${err.message}\n`);
83
+ });
84
+ const multimodalMessage = buildMultimodalMessage(prompt, config.imageAttachments);
85
+ claudeProcess.stdin.write(multimodalMessage);
86
+ claudeProcess.stdin.end();
87
+ }
88
+ // ========== Process Spawning ==========
89
+ /** Spawn the Claude CLI process and register it */
90
+ export function spawnAndRegister(config, prompt, hasImageAttachments, useStreamJson, runningProcesses, perfStart) {
91
+ const mcpConfigPath = generateMcpConfig(config.workingDir, config.verbose);
92
+ if (!mcpConfigPath && config.outputCallback) {
93
+ config.outputCallback('\n[[MSTRO_ERROR:BOUNCER_UNAVAILABLE]] Security bouncer not available. Running with limited permissions — file edits allowed, but shell commands may be restricted.\n');
94
+ }
95
+ const args = buildClaudeArgs(config, prompt, hasImageAttachments, useStreamJson, mcpConfigPath);
96
+ verboseLog(config.verbose, `[PERF] About to spawn: ${Date.now() - perfStart}ms`, `[PERF] Command: ${config.claudeCommand} ${args.join(' ')}`);
97
+ const baseEnv = config.sandboxed
98
+ ? sanitizeEnvForSandbox(process.env, config.workingDir)
99
+ : { ...process.env };
100
+ const spawnEnv = config.extraEnv
101
+ ? { ...baseEnv, ...config.extraEnv }
102
+ : baseEnv;
103
+ const claudeProcess = spawn(config.claudeCommand, args, {
104
+ cwd: config.workingDir,
105
+ detached: true,
106
+ env: spawnEnv,
107
+ stdio: [hasImageAttachments ? 'pipe' : 'ignore', 'pipe', 'pipe']
108
+ });
109
+ if (hasImageAttachments && claudeProcess.stdin) {
110
+ writeImageAttachmentsToStdin(claudeProcess, prompt, config);
111
+ }
112
+ if (claudeProcess.pid) {
113
+ runningProcesses.set(claudeProcess.pid, claudeProcess);
114
+ }
115
+ verboseLog(config.verbose, `[PERF] Spawned: ${Date.now() - perfStart}ms`);
116
+ return claudeProcess;
117
+ }
118
+ // ========== Result Building ==========
119
+ export function buildCloseResult(ctx, stdout, stderr, code, signal, sessionCapture) {
120
+ const postTimeout = flushNativeTimeoutBuffers(ctx);
121
+ const resumeBuffered = ctx.resumeAssessmentActive ? (ctx.resumeAssessmentBuffer || undefined) : undefined;
122
+ const exitCode = code ?? (signal ? 128 + (signalToNumber(signal) ?? 0) : 0);
123
+ const hasTokenUsage = ctx.apiTokenUsage.inputTokens > 0 || ctx.apiTokenUsage.outputTokens > 0;
124
+ return {
125
+ output: stdout,
126
+ error: stderr || undefined,
127
+ exitCode,
128
+ signalName: signal || undefined,
129
+ assistantResponse: ctx.accumulatedAssistantResponse || undefined,
130
+ thinkingOutput: ctx.accumulatedThinking || undefined,
131
+ toolUseHistory: ctx.accumulatedToolUse.length > 0 ? ctx.accumulatedToolUse : undefined,
132
+ claudeSessionId: sessionCapture.claudeSessionId,
133
+ nativeTimeoutCount: ctx.nativeTimeoutDetector.timeoutCount || undefined,
134
+ postTimeoutOutput: postTimeout,
135
+ resumeBufferedOutput: resumeBuffered,
136
+ apiTokenUsage: hasTokenUsage ? { ...ctx.apiTokenUsage } : undefined,
137
+ stopReason: ctx.stopReason,
138
+ };
139
+ }
140
+ //# sourceMappingURL=claude-invoker-process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-invoker-process.js","sourceRoot":"","sources":["../../../../server/cli/headless/claude-invoker-process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { ChildProcess } from 'node:child_process';
2
+ import { type StallContext } from './stall-assessor.js';
3
+ import type { ResolvedHeadlessConfig } from './types.js';
4
+ export interface StallAssessmentParams {
5
+ stallCtx: StallContext;
6
+ config: ResolvedHeadlessConfig;
7
+ now: number;
8
+ extensionsGranted: number;
9
+ maxExtensions: number;
10
+ toolWatchdogActive?: boolean;
11
+ }
12
+ /** Mutable state for stall detection, shared between the interval callback and the outer function */
13
+ export interface StallState {
14
+ lastActivityTime: number;
15
+ stallWarningEmitted: boolean;
16
+ assessmentInProgress: boolean;
17
+ extensionsGranted: number;
18
+ currentKillDeadline: number;
19
+ nextWarningAfter: number;
20
+ }
21
+ /** Terminate a stalled process: SIGTERM then SIGKILL after 5s */
22
+ export declare function terminateStallProcess(claudeProcess: ChildProcess, interval: ReturnType<typeof setInterval>, config: ResolvedHeadlessConfig, message: string): void;
23
+ /** Run a single stall-check tick */
24
+ export declare function runStallCheckTick(state: StallState, opts: {
25
+ perfStart: number;
26
+ stallWarningMs: number;
27
+ stallHardCapMs: number;
28
+ maxExtensions: number;
29
+ stallAssessEnabled: boolean;
30
+ toolWatchdogActive: boolean;
31
+ prompt: string;
32
+ pendingTools: Map<string, string>;
33
+ lastToolInputSummary: string | undefined;
34
+ totalToolCalls: number;
35
+ claudeProcess: ChildProcess;
36
+ stallCheckInterval: ReturnType<typeof setInterval>;
37
+ config: ResolvedHeadlessConfig;
38
+ lastTokenActivityTime: number;
39
+ }): Promise<void>;
40
+ //# sourceMappingURL=claude-invoker-stall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-invoker-stall.d.ts","sourceRoot":"","sources":["../../../../server/cli/headless/claude-invoker-stall.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,qGAAqG;AACrG,MAAM,WAAW,UAAU;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,iEAAiE;AACjE,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,YAAY,EAC3B,QAAQ,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,EACxC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,MAAM,GACd,IAAI,CASN;AA2CD,oCAAoC;AACpC,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE;IACJ,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,YAAY,CAAC;IAC5B,kBAAkB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACnD,MAAM,EAAE,sBAAsB,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;CAC/B,GACA,OAAO,CAAC,IAAI,CAAC,CA0Df"}
@@ -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
+ import { hlog } from './headless-logger.js';
4
+ import { killProcessGroup } from './runner.js';
5
+ import { assessStall } from './stall-assessor.js';
6
+ /** Terminate a stalled process: SIGTERM then SIGKILL after 5s */
7
+ export function terminateStallProcess(claudeProcess, interval, config, message) {
8
+ clearInterval(interval);
9
+ config.outputCallback?.(message);
10
+ if (claudeProcess.pid)
11
+ killProcessGroup(claudeProcess.pid, 'SIGTERM');
12
+ setTimeout(() => {
13
+ if (!claudeProcess.killed && claudeProcess.pid) {
14
+ killProcessGroup(claudeProcess.pid, 'SIGKILL');
15
+ }
16
+ }, 5000);
17
+ }
18
+ /** Run stall assessment and return updated state if extended, null otherwise */
19
+ async function runStallAssessment(params) {
20
+ const { stallCtx, config, now, extensionsGranted, maxExtensions, toolWatchdogActive } = params;
21
+ try {
22
+ const verdict = await assessStall(stallCtx, config.claudeCommand, config.verbose, toolWatchdogActive);
23
+ if (verdict.action === 'extend') {
24
+ const newExtensions = extensionsGranted + 1;
25
+ const elapsedMin = Math.round(stallCtx.elapsedTotalMs / 60_000);
26
+ const pendingNames = stallCtx.pendingToolNames ?? new Set();
27
+ const isAgentTeamsLead = verdict.reason.includes('Agent Teams lead');
28
+ if (pendingNames.has('Task') || isAgentTeamsLead) {
29
+ config.outputCallback?.(`\n[[MSTRO_STALL_EXTENDED]] ${isAgentTeamsLead ? 'Teammates still working' : 'Task subagent still running'} (${elapsedMin} min elapsed). ${verdict.reason}.\n`);
30
+ }
31
+ else {
32
+ config.outputCallback?.(`\n[[MSTRO_STALL_EXTENDED]] Process still working (${elapsedMin} min elapsed). ${verdict.reason}. Extension ${newExtensions}/${maxExtensions}.\n`);
33
+ }
34
+ if (config.verbose) {
35
+ hlog(`[STALL] Extended by ${Math.round(verdict.extensionMs / 60_000)} min: ${verdict.reason}`);
36
+ }
37
+ return { extensionsGranted: newExtensions, currentKillDeadline: now + verdict.extensionMs };
38
+ }
39
+ config.outputCallback?.(`\n[[MSTRO_STALL_CONFIRMED]] Assessment: process likely stalled. ${verdict.reason}.\n`);
40
+ if (config.verbose) {
41
+ hlog(`[STALL] Assessment says stalled: ${verdict.reason}`);
42
+ }
43
+ }
44
+ catch (err) {
45
+ if (config.verbose) {
46
+ hlog(`[STALL] Assessment error: ${err}`);
47
+ }
48
+ }
49
+ return null;
50
+ }
51
+ /** Run a single stall-check tick */
52
+ export async function runStallCheckTick(state, opts) {
53
+ const now = Date.now();
54
+ const silenceMs = now - state.lastActivityTime;
55
+ const totalElapsed = now - opts.perfStart;
56
+ const tokenSilenceMs = now - opts.lastTokenActivityTime;
57
+ if (totalElapsed >= opts.stallHardCapMs) {
58
+ terminateStallProcess(opts.claudeProcess, opts.stallCheckInterval, opts.config, `\n[[MSTRO_ERROR:EXECUTION_STALLED]] Hard time limit reached (${Math.round(opts.stallHardCapMs / 60000)} min total). Terminating process.\n`);
59
+ return;
60
+ }
61
+ // Token activity pushes the kill deadline forward
62
+ if (tokenSilenceMs < 60_000 && now < state.currentKillDeadline) {
63
+ const killMs = opts.config.stallKillMs ?? 1_800_000;
64
+ state.currentKillDeadline = Math.max(state.currentKillDeadline, now + killMs);
65
+ }
66
+ if (now >= state.currentKillDeadline) {
67
+ terminateStallProcess(opts.claudeProcess, opts.stallCheckInterval, opts.config, `\n[[MSTRO_ERROR:EXECUTION_STALLED]] No output for ${Math.round(silenceMs / 60_000)} minutes. Terminating process.\n`);
68
+ return;
69
+ }
70
+ if (silenceMs < opts.stallWarningMs || state.stallWarningEmitted || now < state.nextWarningAfter || state.assessmentInProgress)
71
+ return;
72
+ const stallCtx = {
73
+ originalPrompt: opts.prompt,
74
+ silenceMs,
75
+ lastToolName: opts.pendingTools.size > 0 ? Array.from(opts.pendingTools.values()).pop() : undefined,
76
+ lastToolInputSummary: opts.lastToolInputSummary,
77
+ pendingToolCount: opts.pendingTools.size,
78
+ pendingToolNames: new Set(opts.pendingTools.values()),
79
+ totalToolCalls: opts.totalToolCalls,
80
+ elapsedTotalMs: totalElapsed,
81
+ tokenSilenceMs,
82
+ };
83
+ if (opts.stallAssessEnabled && state.extensionsGranted < opts.maxExtensions) {
84
+ state.assessmentInProgress = true;
85
+ const result = await runStallAssessment({ stallCtx, config: opts.config, now, extensionsGranted: state.extensionsGranted, maxExtensions: opts.maxExtensions, toolWatchdogActive: opts.toolWatchdogActive });
86
+ state.assessmentInProgress = false;
87
+ if (result) {
88
+ state.extensionsGranted = result.extensionsGranted;
89
+ state.currentKillDeadline = result.currentKillDeadline;
90
+ state.nextWarningAfter = now + opts.stallWarningMs;
91
+ return;
92
+ }
93
+ }
94
+ state.stallWarningEmitted = true;
95
+ const killIn = Math.round((state.currentKillDeadline - now) / 60_000);
96
+ opts.config.outputCallback?.(`\n[[MSTRO_ERROR:EXECUTION_STALLED]] No output for ${Math.round(silenceMs / 60_000)} minutes. Will terminate in ${killIn} minutes if no activity.\n`);
97
+ }
98
+ //# sourceMappingURL=claude-invoker-stall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-invoker-stall.js","sourceRoot":"","sources":["../../../../server/cli/headless/claude-invoker-stall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { NativeTimeoutDetector } from './native-timeout-detector.js';
2
+ import type { ResolvedHeadlessConfig, ToolUseAccumulator } from './types.js';
3
+ type StreamJson = any;
4
+ export interface StreamHandlerContext {
5
+ config: ResolvedHeadlessConfig;
6
+ accumulatedAssistantResponse: string;
7
+ accumulatedThinking: string;
8
+ accumulatedToolUse: ToolUseAccumulator[];
9
+ toolInputBuffers: Map<number, {
10
+ name: string;
11
+ id: string;
12
+ inputJson: string;
13
+ startTime: number;
14
+ }>;
15
+ nativeTimeoutDetector: NativeTimeoutDetector;
16
+ /** When true, assistant text is buffered instead of forwarded to outputCallback.
17
+ * Active during resume mode until thinking/tool activity confirms Claude has context. */
18
+ resumeAssessmentActive: boolean;
19
+ /** Buffered assistant text during resume assessment */
20
+ resumeAssessmentBuffer: string;
21
+ /** Cumulative API token usage from message_start/message_delta events */
22
+ apiTokenUsage: {
23
+ inputTokens: number;
24
+ outputTokens: number;
25
+ };
26
+ /** Tracks cumulative output_tokens within the current step (message_delta is cumulative per-step) */
27
+ currentStepOutputTokens: number;
28
+ /** Timestamp of the last token usage change (tokens still flowing = process alive) */
29
+ lastTokenActivityTime: number;
30
+ /** Claude Code result event stop_reason (e.g., 'end_turn', 'max_tokens') */
31
+ stopReason?: string;
32
+ }
33
+ /** Log messages when verbose mode is enabled */
34
+ export declare function verboseLog(verbose: boolean | undefined, ...msgs: string[]): void;
35
+ export declare function processStreamEvent(parsed: StreamJson, ctx: StreamHandlerContext): void;
36
+ export declare function processStreamLines(buffer: string, sessionCapture: {
37
+ claudeSessionId?: string;
38
+ }, ctx: StreamHandlerContext): string;
39
+ /** Flush native timeout detector buffers and return post-timeout output if any */
40
+ export declare function flushNativeTimeoutBuffers(ctx: StreamHandlerContext): string | undefined;
41
+ /** Classify unmatched stderr via Haiku when process exits with error */
42
+ export declare function classifyUnmatchedStderr(stderr: string, errorAlreadySurfaced: boolean, code: number | null, config: ResolvedHeadlessConfig): Promise<void>;
43
+ export {};
44
+ //# sourceMappingURL=claude-invoker-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-invoker-stream.d.ts","sourceRoot":"","sources":["../../../../server/cli/headless/claude-invoker-stream.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAE1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAG7E,KAAK,UAAU,GAAG,GAAG,CAAC;AAEtB,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,4BAA4B,EAAE,MAAM,CAAC;IACrC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,kBAAkB,EAAE,CAAC;IACzC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClG,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C;8FAC0F;IAC1F,sBAAsB,EAAE,OAAO,CAAC;IAChC,uDAAuD;IACvD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,yEAAyE;IACzE,aAAa,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7D,qGAAqG;IACrG,uBAAuB,EAAE,MAAM,CAAC;IAChC,sFAAsF;IACtF,qBAAqB,EAAE,MAAM,CAAC;IAC9B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gDAAgD;AAChD,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAIhF;AA8KD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,oBAAoB,GAAG,IAAI,CA2BtF;AA+DD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5C,GAAG,EAAE,oBAAoB,GACxB,MAAM,CAcR;AAED,kFAAkF;AAClF,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,oBAAoB,GAAG,MAAM,GAAG,SAAS,CAUvF;AAED,wEAAwE;AACxE,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,oBAAoB,EAAE,OAAO,EAC7B,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAWf"}