hammoc 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/README.md +422 -403
  2. package/bin/hammoc.js +0 -6
  3. package/package.json +100 -93
  4. package/packages/client/dist/assets/agentExampleHighlight-BgwTm15v.js +1 -0
  5. package/packages/client/dist/assets/commandTokenHighlight-BljHwnrK.js +1 -0
  6. package/packages/client/dist/assets/index-CjyjnXB8.css +32 -0
  7. package/packages/client/dist/assets/index-D3LxqW3f.js +2 -0
  8. package/packages/client/dist/assets/index-NqJdhlek.js +1498 -0
  9. package/packages/client/dist/assets/snippetTokenHighlight-DWsaQXX0.js +1 -0
  10. package/packages/client/dist/index.html +2 -2
  11. package/packages/client/dist/sw.js +1 -1
  12. package/packages/server/dist/app.d.ts.map +1 -1
  13. package/packages/server/dist/app.js +24 -24
  14. package/packages/server/dist/app.js.map +1 -1
  15. package/packages/server/dist/controllers/boardController.d.ts.map +1 -1
  16. package/packages/server/dist/controllers/boardController.js +0 -5
  17. package/packages/server/dist/controllers/boardController.js.map +1 -1
  18. package/packages/server/dist/controllers/claudeMdController.d.ts +26 -0
  19. package/packages/server/dist/controllers/claudeMdController.d.ts.map +1 -0
  20. package/packages/server/dist/controllers/claudeMdController.js +158 -0
  21. package/packages/server/dist/controllers/claudeMdController.js.map +1 -0
  22. package/packages/server/dist/controllers/fileSystemController.d.ts +4 -0
  23. package/packages/server/dist/controllers/fileSystemController.d.ts.map +1 -1
  24. package/packages/server/dist/controllers/fileSystemController.js +20 -2
  25. package/packages/server/dist/controllers/fileSystemController.js.map +1 -1
  26. package/packages/server/dist/controllers/harnessAgentController.d.ts +28 -0
  27. package/packages/server/dist/controllers/harnessAgentController.d.ts.map +1 -0
  28. package/packages/server/dist/controllers/harnessAgentController.js +339 -0
  29. package/packages/server/dist/controllers/harnessAgentController.js.map +1 -0
  30. package/packages/server/dist/controllers/harnessCommandController.d.ts +28 -0
  31. package/packages/server/dist/controllers/harnessCommandController.d.ts.map +1 -0
  32. package/packages/server/dist/controllers/harnessCommandController.js +382 -0
  33. package/packages/server/dist/controllers/harnessCommandController.js.map +1 -0
  34. package/packages/server/dist/controllers/harnessController.d.ts +21 -0
  35. package/packages/server/dist/controllers/harnessController.d.ts.map +1 -0
  36. package/packages/server/dist/controllers/harnessController.js +176 -0
  37. package/packages/server/dist/controllers/harnessController.js.map +1 -0
  38. package/packages/server/dist/controllers/harnessHookController.d.ts +32 -0
  39. package/packages/server/dist/controllers/harnessHookController.d.ts.map +1 -0
  40. package/packages/server/dist/controllers/harnessHookController.js +363 -0
  41. package/packages/server/dist/controllers/harnessHookController.js.map +1 -0
  42. package/packages/server/dist/controllers/harnessLintController.d.ts +18 -0
  43. package/packages/server/dist/controllers/harnessLintController.d.ts.map +1 -0
  44. package/packages/server/dist/controllers/harnessLintController.js +72 -0
  45. package/packages/server/dist/controllers/harnessLintController.js.map +1 -0
  46. package/packages/server/dist/controllers/harnessMcpController.d.ts +28 -0
  47. package/packages/server/dist/controllers/harnessMcpController.d.ts.map +1 -0
  48. package/packages/server/dist/controllers/harnessMcpController.js +310 -0
  49. package/packages/server/dist/controllers/harnessMcpController.js.map +1 -0
  50. package/packages/server/dist/controllers/harnessPluginController.d.ts +17 -0
  51. package/packages/server/dist/controllers/harnessPluginController.d.ts.map +1 -0
  52. package/packages/server/dist/controllers/harnessPluginController.js +115 -0
  53. package/packages/server/dist/controllers/harnessPluginController.js.map +1 -0
  54. package/packages/server/dist/controllers/harnessShareScopeController.d.ts +15 -0
  55. package/packages/server/dist/controllers/harnessShareScopeController.d.ts.map +1 -0
  56. package/packages/server/dist/controllers/harnessShareScopeController.js +73 -0
  57. package/packages/server/dist/controllers/harnessShareScopeController.js.map +1 -0
  58. package/packages/server/dist/controllers/harnessSkillController.d.ts +32 -0
  59. package/packages/server/dist/controllers/harnessSkillController.d.ts.map +1 -0
  60. package/packages/server/dist/controllers/harnessSkillController.js +453 -0
  61. package/packages/server/dist/controllers/harnessSkillController.js.map +1 -0
  62. package/packages/server/dist/controllers/projectController.d.ts.map +1 -1
  63. package/packages/server/dist/controllers/projectController.js +11 -0
  64. package/packages/server/dist/controllers/projectController.js.map +1 -1
  65. package/packages/server/dist/controllers/serverController.d.ts.map +1 -1
  66. package/packages/server/dist/controllers/serverController.js +84 -49
  67. package/packages/server/dist/controllers/serverController.js.map +1 -1
  68. package/packages/server/dist/controllers/snippetController.d.ts +35 -0
  69. package/packages/server/dist/controllers/snippetController.d.ts.map +1 -0
  70. package/packages/server/dist/controllers/snippetController.js +294 -0
  71. package/packages/server/dist/controllers/snippetController.js.map +1 -0
  72. package/packages/server/dist/handlers/websocket.d.ts +16 -0
  73. package/packages/server/dist/handlers/websocket.d.ts.map +1 -1
  74. package/packages/server/dist/handlers/websocket.js +221 -8
  75. package/packages/server/dist/handlers/websocket.js.map +1 -1
  76. package/packages/server/dist/index.js +66 -0
  77. package/packages/server/dist/index.js.map +1 -1
  78. package/packages/server/dist/locales/en/server.json +41 -6
  79. package/packages/server/dist/locales/es/server.json +3 -5
  80. package/packages/server/dist/locales/ja/server.json +3 -5
  81. package/packages/server/dist/locales/ko/server.json +4 -6
  82. package/packages/server/dist/locales/pt/server.json +3 -5
  83. package/packages/server/dist/locales/zh-CN/server.json +3 -5
  84. package/packages/server/dist/routes/account.d.ts +7 -0
  85. package/packages/server/dist/routes/account.d.ts.map +1 -0
  86. package/packages/server/dist/routes/account.js +35 -0
  87. package/packages/server/dist/routes/account.js.map +1 -0
  88. package/packages/server/dist/routes/debug.d.ts +1 -1
  89. package/packages/server/dist/routes/debug.d.ts.map +1 -1
  90. package/packages/server/dist/routes/debug.js +60 -1
  91. package/packages/server/dist/routes/debug.js.map +1 -1
  92. package/packages/server/dist/routes/harness.d.ts +8 -0
  93. package/packages/server/dist/routes/harness.d.ts.map +1 -0
  94. package/packages/server/dist/routes/harness.js +92 -0
  95. package/packages/server/dist/routes/harness.js.map +1 -0
  96. package/packages/server/dist/routes/preferences.d.ts.map +1 -1
  97. package/packages/server/dist/routes/preferences.js +11 -2
  98. package/packages/server/dist/routes/preferences.js.map +1 -1
  99. package/packages/server/dist/routes/projects.d.ts.map +1 -1
  100. package/packages/server/dist/routes/projects.js +5 -60
  101. package/packages/server/dist/routes/projects.js.map +1 -1
  102. package/packages/server/dist/routes/snippets.d.ts +14 -0
  103. package/packages/server/dist/routes/snippets.d.ts.map +1 -0
  104. package/packages/server/dist/routes/snippets.js +27 -0
  105. package/packages/server/dist/routes/snippets.js.map +1 -0
  106. package/packages/server/dist/services/accountInfoService.d.ts +38 -0
  107. package/packages/server/dist/services/accountInfoService.d.ts.map +1 -0
  108. package/packages/server/dist/services/accountInfoService.js +118 -0
  109. package/packages/server/dist/services/accountInfoService.js.map +1 -0
  110. package/packages/server/dist/services/bmadStatusService.d.ts +6 -2
  111. package/packages/server/dist/services/bmadStatusService.d.ts.map +1 -1
  112. package/packages/server/dist/services/bmadStatusService.js +88 -32
  113. package/packages/server/dist/services/bmadStatusService.js.map +1 -1
  114. package/packages/server/dist/services/chatService.d.ts +3 -0
  115. package/packages/server/dist/services/chatService.d.ts.map +1 -1
  116. package/packages/server/dist/services/chatService.js +36 -8
  117. package/packages/server/dist/services/chatService.js.map +1 -1
  118. package/packages/server/dist/services/claudeMdService.d.ts +48 -0
  119. package/packages/server/dist/services/claudeMdService.d.ts.map +1 -0
  120. package/packages/server/dist/services/claudeMdService.js +240 -0
  121. package/packages/server/dist/services/claudeMdService.js.map +1 -0
  122. package/packages/server/dist/services/commandService.d.ts +10 -0
  123. package/packages/server/dist/services/commandService.d.ts.map +1 -1
  124. package/packages/server/dist/services/commandService.js +129 -4
  125. package/packages/server/dist/services/commandService.js.map +1 -1
  126. package/packages/server/dist/services/fileSystemService.d.ts +7 -1
  127. package/packages/server/dist/services/fileSystemService.d.ts.map +1 -1
  128. package/packages/server/dist/services/fileSystemService.js +67 -8
  129. package/packages/server/dist/services/fileSystemService.js.map +1 -1
  130. package/packages/server/dist/services/fileWatcherService.d.ts +59 -0
  131. package/packages/server/dist/services/fileWatcherService.d.ts.map +1 -0
  132. package/packages/server/dist/services/fileWatcherService.js +329 -0
  133. package/packages/server/dist/services/fileWatcherService.js.map +1 -0
  134. package/packages/server/dist/services/gitService.d.ts.map +1 -1
  135. package/packages/server/dist/services/gitService.js +67 -7
  136. package/packages/server/dist/services/gitService.js.map +1 -1
  137. package/packages/server/dist/services/harnessAgentService.d.ts +79 -0
  138. package/packages/server/dist/services/harnessAgentService.d.ts.map +1 -0
  139. package/packages/server/dist/services/harnessAgentService.js +933 -0
  140. package/packages/server/dist/services/harnessAgentService.js.map +1 -0
  141. package/packages/server/dist/services/harnessCommandService.d.ts +60 -0
  142. package/packages/server/dist/services/harnessCommandService.d.ts.map +1 -0
  143. package/packages/server/dist/services/harnessCommandService.js +853 -0
  144. package/packages/server/dist/services/harnessCommandService.js.map +1 -0
  145. package/packages/server/dist/services/harnessHookService.d.ts +55 -0
  146. package/packages/server/dist/services/harnessHookService.d.ts.map +1 -0
  147. package/packages/server/dist/services/harnessHookService.js +1060 -0
  148. package/packages/server/dist/services/harnessHookService.js.map +1 -0
  149. package/packages/server/dist/services/harnessLintService.d.ts +49 -0
  150. package/packages/server/dist/services/harnessLintService.d.ts.map +1 -0
  151. package/packages/server/dist/services/harnessLintService.js +628 -0
  152. package/packages/server/dist/services/harnessLintService.js.map +1 -0
  153. package/packages/server/dist/services/harnessMcpService.d.ts +77 -0
  154. package/packages/server/dist/services/harnessMcpService.d.ts.map +1 -0
  155. package/packages/server/dist/services/harnessMcpService.js +814 -0
  156. package/packages/server/dist/services/harnessMcpService.js.map +1 -0
  157. package/packages/server/dist/services/harnessPluginService.d.ts +66 -0
  158. package/packages/server/dist/services/harnessPluginService.d.ts.map +1 -0
  159. package/packages/server/dist/services/harnessPluginService.js +559 -0
  160. package/packages/server/dist/services/harnessPluginService.js.map +1 -0
  161. package/packages/server/dist/services/harnessService.d.ts +40 -0
  162. package/packages/server/dist/services/harnessService.d.ts.map +1 -0
  163. package/packages/server/dist/services/harnessService.js +222 -0
  164. package/packages/server/dist/services/harnessService.js.map +1 -0
  165. package/packages/server/dist/services/harnessShareScopeService.d.ts +31 -0
  166. package/packages/server/dist/services/harnessShareScopeService.d.ts.map +1 -0
  167. package/packages/server/dist/services/harnessShareScopeService.js +93 -0
  168. package/packages/server/dist/services/harnessShareScopeService.js.map +1 -0
  169. package/packages/server/dist/services/harnessSkillService.d.ts +70 -0
  170. package/packages/server/dist/services/harnessSkillService.d.ts.map +1 -0
  171. package/packages/server/dist/services/harnessSkillService.js +636 -0
  172. package/packages/server/dist/services/harnessSkillService.js.map +1 -0
  173. package/packages/server/dist/services/historyParser.d.ts +4 -14
  174. package/packages/server/dist/services/historyParser.d.ts.map +1 -1
  175. package/packages/server/dist/services/historyParser.js +60 -5
  176. package/packages/server/dist/services/historyParser.js.map +1 -1
  177. package/packages/server/dist/services/issueService.d.ts.map +1 -1
  178. package/packages/server/dist/services/issueService.js +10 -2
  179. package/packages/server/dist/services/issueService.js.map +1 -1
  180. package/packages/server/dist/services/manualSyncService.d.ts +19 -0
  181. package/packages/server/dist/services/manualSyncService.d.ts.map +1 -0
  182. package/packages/server/dist/services/manualSyncService.js +110 -0
  183. package/packages/server/dist/services/manualSyncService.js.map +1 -0
  184. package/packages/server/dist/services/notificationService.d.ts.map +1 -1
  185. package/packages/server/dist/services/notificationService.js +34 -9
  186. package/packages/server/dist/services/notificationService.js.map +1 -1
  187. package/packages/server/dist/services/preferencesService.d.ts.map +1 -1
  188. package/packages/server/dist/services/preferencesService.js +8 -1
  189. package/packages/server/dist/services/preferencesService.js.map +1 -1
  190. package/packages/server/dist/services/projectService.d.ts +5 -0
  191. package/packages/server/dist/services/projectService.d.ts.map +1 -1
  192. package/packages/server/dist/services/projectService.js +42 -2
  193. package/packages/server/dist/services/projectService.js.map +1 -1
  194. package/packages/server/dist/services/ptyService.d.ts +1 -0
  195. package/packages/server/dist/services/ptyService.d.ts.map +1 -1
  196. package/packages/server/dist/services/ptyService.js +36 -5
  197. package/packages/server/dist/services/ptyService.js.map +1 -1
  198. package/packages/server/dist/services/queueService.d.ts.map +1 -1
  199. package/packages/server/dist/services/queueService.js +83 -14
  200. package/packages/server/dist/services/queueService.js.map +1 -1
  201. package/packages/server/dist/services/sessionBufferManager.d.ts.map +1 -1
  202. package/packages/server/dist/services/sessionBufferManager.js +26 -0
  203. package/packages/server/dist/services/sessionBufferManager.js.map +1 -1
  204. package/packages/server/dist/services/sessionService.d.ts +4 -3
  205. package/packages/server/dist/services/sessionService.d.ts.map +1 -1
  206. package/packages/server/dist/services/sessionService.js +5 -4
  207. package/packages/server/dist/services/sessionService.js.map +1 -1
  208. package/packages/server/dist/services/snippetService.d.ts +54 -0
  209. package/packages/server/dist/services/snippetService.d.ts.map +1 -0
  210. package/packages/server/dist/services/snippetService.js +371 -0
  211. package/packages/server/dist/services/snippetService.js.map +1 -0
  212. package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.d.ts +46 -0
  213. package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.d.ts.map +1 -0
  214. package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.js +125 -0
  215. package/packages/server/dist/services/utils/applyYamlFrontmatterPatch.js.map +1 -0
  216. package/packages/server/dist/services/webPushService.d.ts.map +1 -1
  217. package/packages/server/dist/services/webPushService.js +8 -1
  218. package/packages/server/dist/services/webPushService.js.map +1 -1
  219. package/packages/server/dist/snippets/split-commit +9 -0
  220. package/packages/server/dist/utils/applySecretsPolicy.d.ts +53 -0
  221. package/packages/server/dist/utils/applySecretsPolicy.d.ts.map +1 -0
  222. package/packages/server/dist/utils/applySecretsPolicy.js +204 -0
  223. package/packages/server/dist/utils/applySecretsPolicy.js.map +1 -0
  224. package/packages/server/dist/utils/assertNoSecretOnShared.d.ts +40 -0
  225. package/packages/server/dist/utils/assertNoSecretOnShared.d.ts.map +1 -0
  226. package/packages/server/dist/utils/assertNoSecretOnShared.js +47 -0
  227. package/packages/server/dist/utils/assertNoSecretOnShared.js.map +1 -0
  228. package/packages/server/dist/utils/effortUtils.d.ts +21 -0
  229. package/packages/server/dist/utils/effortUtils.d.ts.map +1 -0
  230. package/packages/server/dist/utils/effortUtils.js +36 -0
  231. package/packages/server/dist/utils/effortUtils.js.map +1 -0
  232. package/packages/server/dist/utils/gitignoreFilter.d.ts +23 -0
  233. package/packages/server/dist/utils/gitignoreFilter.d.ts.map +1 -0
  234. package/packages/server/dist/utils/gitignoreFilter.js +42 -0
  235. package/packages/server/dist/utils/gitignoreFilter.js.map +1 -0
  236. package/packages/server/dist/utils/harnessBundleSchema.d.ts +105 -0
  237. package/packages/server/dist/utils/harnessBundleSchema.d.ts.map +1 -0
  238. package/packages/server/dist/utils/harnessBundleSchema.js +79 -0
  239. package/packages/server/dist/utils/harnessBundleSchema.js.map +1 -0
  240. package/packages/server/dist/utils/harnessPaths.d.ts +34 -0
  241. package/packages/server/dist/utils/harnessPaths.d.ts.map +1 -0
  242. package/packages/server/dist/utils/harnessPaths.js +124 -0
  243. package/packages/server/dist/utils/harnessPaths.js.map +1 -0
  244. package/packages/server/dist/utils/pathUtils.d.ts +3 -2
  245. package/packages/server/dist/utils/pathUtils.d.ts.map +1 -1
  246. package/packages/server/dist/utils/pathUtils.js +26 -2
  247. package/packages/server/dist/utils/pathUtils.js.map +1 -1
  248. package/packages/server/dist/utils/secretHeuristic.d.ts +72 -0
  249. package/packages/server/dist/utils/secretHeuristic.d.ts.map +1 -0
  250. package/packages/server/dist/utils/secretHeuristic.js +163 -0
  251. package/packages/server/dist/utils/secretHeuristic.js.map +1 -0
  252. package/packages/server/dist/utils/secretPlaceholderNamer.d.ts +41 -0
  253. package/packages/server/dist/utils/secretPlaceholderNamer.d.ts.map +1 -0
  254. package/packages/server/dist/utils/secretPlaceholderNamer.js +81 -0
  255. package/packages/server/dist/utils/secretPlaceholderNamer.js.map +1 -0
  256. package/packages/server/dist/utils/serverPathResolver.d.ts +29 -0
  257. package/packages/server/dist/utils/serverPathResolver.d.ts.map +1 -0
  258. package/packages/server/dist/utils/serverPathResolver.js +59 -0
  259. package/packages/server/dist/utils/serverPathResolver.js.map +1 -0
  260. package/packages/server/dist/utils/snippetPaths.d.ts +61 -0
  261. package/packages/server/dist/utils/snippetPaths.d.ts.map +1 -0
  262. package/packages/server/dist/utils/snippetPaths.js +123 -0
  263. package/packages/server/dist/utils/snippetPaths.js.map +1 -0
  264. package/packages/server/dist/utils/structuredEditor.d.ts +34 -0
  265. package/packages/server/dist/utils/structuredEditor.d.ts.map +1 -0
  266. package/packages/server/dist/utils/structuredEditor.js +111 -0
  267. package/packages/server/dist/utils/structuredEditor.js.map +1 -0
  268. package/packages/server/package.json +6 -2
  269. package/packages/server/resources/internals/INDEX.md +23 -0
  270. package/packages/server/resources/internals/harness-files.md +63 -0
  271. package/packages/server/resources/internals/image-storage.md +43 -0
  272. package/packages/server/resources/manual/01-getting-started.md +104 -0
  273. package/packages/server/resources/manual/02-chat.md +285 -0
  274. package/packages/server/resources/manual/03-sessions.md +48 -0
  275. package/packages/server/resources/manual/04-slash-commands-favorites.md +152 -0
  276. package/packages/server/resources/manual/05-projects.md +74 -0
  277. package/packages/server/resources/manual/06-file-explorer-editor.md +90 -0
  278. package/packages/server/resources/manual/07-git.md +94 -0
  279. package/packages/server/resources/manual/08-terminal.md +59 -0
  280. package/packages/server/resources/manual/09-queue-runner.md +262 -0
  281. package/packages/server/resources/manual/10-project-board.md +193 -0
  282. package/packages/server/resources/manual/11-bmad-method-integration.md +128 -0
  283. package/packages/server/resources/manual/12-harness-workbench.md +175 -0
  284. package/packages/server/resources/manual/13-settings.md +241 -0
  285. package/packages/server/resources/manual/14-keyboard-shortcuts.md +68 -0
  286. package/packages/server/resources/manual/15-environment-variables.md +28 -0
  287. package/packages/server/resources/manual/16-troubleshooting.md +110 -0
  288. package/packages/server/resources/manual/INDEX.md +60 -0
  289. package/packages/shared/dist/index.d.ts +3 -0
  290. package/packages/shared/dist/index.d.ts.map +1 -1
  291. package/packages/shared/dist/index.js +6 -0
  292. package/packages/shared/dist/index.js.map +1 -1
  293. package/packages/shared/dist/types/command.d.ts +3 -3
  294. package/packages/shared/dist/types/command.d.ts.map +1 -1
  295. package/packages/shared/dist/types/fileSystem.d.ts +19 -0
  296. package/packages/shared/dist/types/fileSystem.d.ts.map +1 -1
  297. package/packages/shared/dist/types/fileSystem.js +5 -0
  298. package/packages/shared/dist/types/fileSystem.js.map +1 -1
  299. package/packages/shared/dist/types/git.d.ts +6 -1
  300. package/packages/shared/dist/types/git.d.ts.map +1 -1
  301. package/packages/shared/dist/types/git.js.map +1 -1
  302. package/packages/shared/dist/types/harness.d.ts +1211 -0
  303. package/packages/shared/dist/types/harness.d.ts.map +1 -0
  304. package/packages/shared/dist/types/harness.js +107 -0
  305. package/packages/shared/dist/types/harness.js.map +1 -0
  306. package/packages/shared/dist/types/harnessBundle.d.ts +170 -0
  307. package/packages/shared/dist/types/harnessBundle.d.ts.map +1 -0
  308. package/packages/shared/dist/types/harnessBundle.js +18 -0
  309. package/packages/shared/dist/types/harnessBundle.js.map +1 -0
  310. package/packages/shared/dist/types/history.d.ts +7 -0
  311. package/packages/shared/dist/types/history.d.ts.map +1 -1
  312. package/packages/shared/dist/types/preferences.d.ts +4 -1
  313. package/packages/shared/dist/types/preferences.d.ts.map +1 -1
  314. package/packages/shared/dist/types/preferences.js +1 -0
  315. package/packages/shared/dist/types/preferences.js.map +1 -1
  316. package/packages/shared/dist/types/queue.d.ts +9 -0
  317. package/packages/shared/dist/types/queue.d.ts.map +1 -1
  318. package/packages/shared/dist/types/sdk.d.ts +42 -1
  319. package/packages/shared/dist/types/sdk.d.ts.map +1 -1
  320. package/packages/shared/dist/types/sdk.js +26 -2
  321. package/packages/shared/dist/types/sdk.js.map +1 -1
  322. package/packages/shared/dist/types/websocket.d.ts +24 -0
  323. package/packages/shared/dist/types/websocket.d.ts.map +1 -1
  324. package/packages/shared/dist/utils/markdownSections.d.ts +50 -0
  325. package/packages/shared/dist/utils/markdownSections.d.ts.map +1 -0
  326. package/packages/shared/dist/utils/markdownSections.js +111 -0
  327. package/packages/shared/dist/utils/markdownSections.js.map +1 -0
  328. package/packages/shared/dist/utils/queueParser.d.ts.map +1 -1
  329. package/packages/shared/dist/utils/queueParser.js +104 -0
  330. package/packages/shared/dist/utils/queueParser.js.map +1 -1
  331. package/scripts/build-manual-shards.mjs +100 -0
  332. package/scripts/mock-telegram.mjs +172 -0
  333. package/scripts/run-integration-test.mjs +362 -0
  334. package/packages/client/dist/assets/index-Bf0D9oVJ.css +0 -32
  335. package/packages/client/dist/assets/index-CRmzoqHy.js +0 -2
  336. package/packages/client/dist/assets/index-CszGQ29O.js +0 -1432
@@ -21,11 +21,13 @@ import { notificationService, formatAskQuestionPrompt } from '../services/notifi
21
21
  import { preferencesService } from '../services/preferencesService.js';
22
22
  import { getOrCreateQueueService, getQueueInstances } from '../controllers/queueController.js';
23
23
  import { createLogger } from '../utils/logger.js';
24
+ import { clampEffortForModel, supportsAdaptiveThinking } from '../utils/effortUtils.js';
24
25
  import { buildStreamCallbacks } from './streamCallbacks.js';
25
26
  import { rateLimitProbeService } from '../services/rateLimitProbeService.js';
26
27
  import { ptyService } from '../services/ptyService.js';
27
28
  import { projectService } from '../services/projectService.js';
28
29
  import { dashboardService } from '../services/dashboardService.js';
30
+ import { fileWatcherService } from '../services/fileWatcherService.js';
29
31
  import { summarize } from '../services/summarizeService.js';
30
32
  import { parseJSONLFile, transformToHistoryMessages } from '../services/historyParser.js';
31
33
  import { buildRawMessageTree, getActiveRawBranch, getDefaultRawBranchSelections, findBranchSelectionsForUuid } from '../utils/messageTree.js';
@@ -93,6 +95,10 @@ const socketToSession = new Map();
93
95
  const socketSessionRoom = new Map();
94
96
  // Track which project room each socket joined (for leave on session switch)
95
97
  const socketProjectRoom = new Map();
98
+ // Story 28.0.5: Track harness rooms each socket has subscribed to, so we can
99
+ // release watcher ref counts on disconnect without leaking chokidar instances.
100
+ // Key: socket.id → Set of "harness:user" | "harness:project:<slug>" room strings.
101
+ const socketHarnessRooms = new Map();
96
102
  const chainState = new Map();
97
103
  // Per-session drain generation counter for race guard
98
104
  const chainDrainGeneration = new Map();
@@ -101,6 +107,30 @@ const chainResumableSessions = new Set();
101
107
  let chainItemCounter = 0;
102
108
  const CHAIN_MAX_RETRIES = 3;
103
109
  const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
110
+ // Debug hook: synthetic failure injection for chain drain (G-02-02 retry test).
111
+ // Only consumed when ENABLE_TEST_ENDPOINTS=true; the POST /api/debug route
112
+ // validates the flag before writing to this map.
113
+ const chainDrainFailureInjection = new Map();
114
+ export function setChainDrainFailureInjection(sessionId, count) {
115
+ if (count <= 0) {
116
+ chainDrainFailureInjection.delete(sessionId);
117
+ }
118
+ else {
119
+ chainDrainFailureInjection.set(sessionId, count);
120
+ }
121
+ }
122
+ function consumeChainDrainFailureInjection(sessionId) {
123
+ const remaining = chainDrainFailureInjection.get(sessionId) ?? 0;
124
+ if (remaining <= 0)
125
+ return false;
126
+ if (remaining === 1) {
127
+ chainDrainFailureInjection.delete(sessionId);
128
+ }
129
+ else {
130
+ chainDrainFailureInjection.set(sessionId, remaining - 1);
131
+ }
132
+ return true;
133
+ }
104
134
  // Story 25.9: Per-socket summarizing state — requestId prevents race between cancel + new request
105
135
  const socketSummarizing = new Map();
106
136
  /** Generate a unique chain item ID */
@@ -232,6 +262,11 @@ function scheduleChainDrain(sessionId, lang) {
232
262
  const abortController = new AbortController();
233
263
  let stream;
234
264
  try {
265
+ // Debug: synthetic failure injection for retry tests (G-02-02).
266
+ // Throws before creating the stream so the retry path is exercised cleanly.
267
+ if (consumeChainDrainFailureInjection(sessionId)) {
268
+ throw new Error('Injected chain drain failure (debug)');
269
+ }
235
270
  // Create headless stream inside try — if this throws, sending status is recovered below
236
271
  const headless = createHeadlessStream(sessionId, abortController);
237
272
  stream = headless.stream;
@@ -701,6 +736,29 @@ export async function initializeWebSocket(httpServer) {
701
736
  cors: config.cors,
702
737
  maxHttpBufferSize: 100 * 1024 * 1024, // 100MB for base64 image payloads
703
738
  });
739
+ // Mirror project-room membership into fileWatcherService so every code path
740
+ // that calls socket.join/leave with a `project:<slug>` room transparently
741
+ // starts or stops the chokidar watcher for that project. socket.io emits
742
+ // join-room/leave-room exactly once per (socket, room) transition, so the
743
+ // service's ref count aligns with the number of sockets currently in the room.
744
+ const projectRoomAdapter = io.of('/').adapter;
745
+ projectRoomAdapter.on('join-room', (room, _id) => {
746
+ if (!room.startsWith('project:'))
747
+ return;
748
+ const slug = room.slice('project:'.length);
749
+ projectService
750
+ .resolveOriginalPath(slug)
751
+ .then((projectRoot) => fileWatcherService.ensureWatcher(slug, projectRoot))
752
+ .catch(() => {
753
+ // Project not found — nothing to watch; silently skip.
754
+ });
755
+ });
756
+ projectRoomAdapter.on('leave-room', (room, _id) => {
757
+ if (!room.startsWith('project:'))
758
+ return;
759
+ const slug = room.slice('project:'.length);
760
+ fileWatcherService.releaseWatcher(slug);
761
+ });
704
762
  // Session middleware for WebSocket (Story 2.5 - Task 4)
705
763
  const sessionMiddleware = await createSessionMiddleware();
706
764
  // Parse session from cookie for Socket.io connections
@@ -765,6 +823,28 @@ export async function initializeWebSocket(httpServer) {
765
823
  });
766
824
  }
767
825
  })();
826
+ // Allow clients to re-request terminal access info (e.g., after late listener registration)
827
+ socket.on('terminal:access:request', () => {
828
+ try {
829
+ const lang = socket.data.language || 'en';
830
+ const t = i18next.getFixedT(lang);
831
+ const clientIP = extractClientIP(socket);
832
+ const isLocal = isLocalIP(clientIP);
833
+ const terminalEnabled = preferencesService.getTerminalEnabled();
834
+ socket.emit('terminal:access', {
835
+ allowed: terminalEnabled && isLocal,
836
+ enabled: terminalEnabled,
837
+ reason: !terminalEnabled
838
+ ? t('ws.error.terminalDisabled')
839
+ : !isLocal
840
+ ? t('ws.error.terminalAccessDenied')
841
+ : undefined,
842
+ });
843
+ }
844
+ catch {
845
+ socket.emit('terminal:access', { allowed: false, enabled: false });
846
+ }
847
+ });
768
848
  // Start rate limit polling on first client connection
769
849
  if (connectedClients === 1) {
770
850
  rateLimitProbeService.startPolling((data) => { io.emit('rateLimit:update', data); }, (data) => { io.emit('apiHealth:update', data); });
@@ -1026,6 +1106,12 @@ export async function initializeWebSocket(httpServer) {
1026
1106
  // Handle session:join event — attach socket to active running stream (broadcast)
1027
1107
  // Also joins a persistent Socket.io room so future streams auto-include this socket.
1028
1108
  socket.on('session:join', (sessionId, projectSlug) => {
1109
+ // Dedup guard: if the same socket re-emits session:join for the same
1110
+ // session it's already in, skip the history / buffer-replay emissions
1111
+ // below. Room and stream.sockets membership are already correct, and
1112
+ // redundant replays on every reconnect (see ea66988 client-side change)
1113
+ // would cost extra bandwidth and trigger unnecessary client re-renders.
1114
+ const alreadyJoinedSame = socketSessionRoom.get(socket.id) === sessionId;
1029
1115
  // Detach this socket from any previously-attached stream to prevent
1030
1116
  // events from the old stream leaking to a different session's listeners
1031
1117
  const prevSessionId = socketToSession.get(socket.id);
@@ -1043,7 +1129,8 @@ export async function initializeWebSocket(httpServer) {
1043
1129
  if (prevRoomSessionId && prevRoomSessionId !== sessionId && prevRoomSessionId !== prevSessionId) {
1044
1130
  socket.leave(`session:${prevRoomSessionId}`);
1045
1131
  }
1046
- // Join persistent session room (survives beyond ActiveStream lifecycle)
1132
+ // Join persistent session room (survives beyond ActiveStream lifecycle).
1133
+ // socket.join() is idempotent — safe to call even if already joined.
1047
1134
  socket.join(`session:${sessionId}`);
1048
1135
  // Leave previous project room if switching projects (or if new join has no projectSlug)
1049
1136
  const prevProjectRoom = socketProjectRoom.get(socket.id);
@@ -1091,6 +1178,13 @@ export async function initializeWebSocket(httpServer) {
1091
1178
  const freshItems = (chainState.get(sessionId) || []).map(toPublicChainItem);
1092
1179
  socket.emit('chain:update', { sessionId, items: freshItems });
1093
1180
  }
1181
+ // Dedup: a duplicate session:join from the already-present socket for
1182
+ // the same session doesn't need history / buffer-replay — the socket
1183
+ // already has them. Room membership and chain:update above are idempotent
1184
+ // and cheap, so we let those run.
1185
+ if (alreadyJoinedSame) {
1186
+ return;
1187
+ }
1094
1188
  if (!stream || stream.status !== 'running') {
1095
1189
  // Story 27.1: Deliver buffer messages via stream:history (no HTTP fetch needed).
1096
1190
  // Wrapped in a helper that re-checks activeStreams because the async
@@ -1382,6 +1476,39 @@ export async function initializeWebSocket(httpServer) {
1382
1476
  log.error(`Failed to remove persisted failure ${id} for session ${sessionId}:`, err);
1383
1477
  });
1384
1478
  });
1479
+ socket.on('chain:reorder', (data) => {
1480
+ if (!data || typeof data !== 'object')
1481
+ return;
1482
+ const { sessionId, ids } = data;
1483
+ if (!sessionId || typeof sessionId !== 'string' || !UUID_RE.test(sessionId))
1484
+ return;
1485
+ if (!Array.isArray(ids) || ids.length === 0)
1486
+ return;
1487
+ if (!ids.every(id => typeof id === 'string'))
1488
+ return;
1489
+ if (!socket.rooms.has(`session:${sessionId}`))
1490
+ return;
1491
+ const currentItems = chainState.get(sessionId);
1492
+ if (!currentItems)
1493
+ return;
1494
+ // Only reorder pending items — sending/sent items are already processed.
1495
+ const nonPending = currentItems.filter(item => item.status !== 'pending');
1496
+ const pendingById = new Map(currentItems.filter(item => item.status === 'pending').map(item => [item.id, item]));
1497
+ const reordered = [];
1498
+ for (const id of ids) {
1499
+ const item = pendingById.get(id);
1500
+ if (item) {
1501
+ reordered.push(item);
1502
+ pendingById.delete(id);
1503
+ }
1504
+ }
1505
+ // Append any pending items not present in ids (safety: preserve unknowns)
1506
+ for (const item of pendingById.values()) {
1507
+ reordered.push(item);
1508
+ }
1509
+ chainState.set(sessionId, [...nonPending, ...reordered]);
1510
+ broadcastChainUpdate(sessionId);
1511
+ });
1385
1512
  socket.on('chain:clear', (data) => {
1386
1513
  if (!data || typeof data !== 'object')
1387
1514
  return;
@@ -1667,6 +1794,10 @@ export async function initializeWebSocket(httpServer) {
1667
1794
  socket.emit('snippets:list', { snippets: [] });
1668
1795
  }
1669
1796
  });
1797
+ // Story 29.2: re-emit `snippets:list` after a snippet CRUD so the
1798
+ // originating client's autocomplete surfaces stay in sync without an
1799
+ // explicit refresh round-trip. This is the same channel the existing
1800
+ // listener above answers, so consumers don't need a new event handler.
1670
1801
  // Handle project:join/leave — room for queue event delivery (Story 15.2)
1671
1802
  socket.on('project:join', (projectSlug) => {
1672
1803
  socket.join(`project:${projectSlug}`);
@@ -1679,6 +1810,37 @@ export async function initializeWebSocket(httpServer) {
1679
1810
  socketProjectRoom.delete(socket.id);
1680
1811
  }
1681
1812
  });
1813
+ // Story 28.0.5: Harness workbench subscription — one room per scope.
1814
+ socket.on('harness:subscribe', async ({ scope, projectSlug }) => {
1815
+ const room = scope === 'user' ? 'harness:user' : `harness:project:${projectSlug ?? ''}`;
1816
+ await socket.join(room);
1817
+ let rooms = socketHarnessRooms.get(socket.id);
1818
+ if (!rooms) {
1819
+ rooms = new Set();
1820
+ socketHarnessRooms.set(socket.id, rooms);
1821
+ }
1822
+ // Idempotent subscribe: increment the watcher ref count only on the
1823
+ // first join so disconnect cleanup matches exactly.
1824
+ if (!rooms.has(room)) {
1825
+ rooms.add(room);
1826
+ try {
1827
+ await fileWatcherService.ensureHarnessWatcher({ scope, projectSlug });
1828
+ }
1829
+ catch (err) {
1830
+ log.warn(`harness:subscribe watcher failed for ${room}: ${String(err)}`);
1831
+ }
1832
+ }
1833
+ });
1834
+ socket.on('harness:unsubscribe', async ({ scope, projectSlug }) => {
1835
+ const room = scope === 'user' ? 'harness:user' : `harness:project:${projectSlug ?? ''}`;
1836
+ await socket.leave(room);
1837
+ const rooms = socketHarnessRooms.get(socket.id);
1838
+ if (rooms && rooms.delete(room)) {
1839
+ fileWatcherService.releaseHarnessWatcher({ scope, projectSlug });
1840
+ if (rooms.size === 0)
1841
+ socketHarnessRooms.delete(socket.id);
1842
+ }
1843
+ });
1682
1844
  // Handle queue events via WebSocket (Story 15.2)
1683
1845
  socket.on('queue:start', async (data) => {
1684
1846
  const { items, sessionId, projectSlug, permissionMode } = data;
@@ -1946,6 +2108,21 @@ export async function initializeWebSocket(httpServer) {
1946
2108
  }
1947
2109
  }
1948
2110
  socketProjectRoom.delete(socket.id);
2111
+ // Story 28.0.5: Release any harness watcher refs held by this socket so
2112
+ // chokidar instances don't leak when a client drops without unsubscribing.
2113
+ const harnessRooms = socketHarnessRooms.get(socket.id);
2114
+ if (harnessRooms) {
2115
+ for (const room of harnessRooms) {
2116
+ if (room === 'harness:user') {
2117
+ fileWatcherService.releaseHarnessWatcher({ scope: 'user' });
2118
+ }
2119
+ else if (room.startsWith('harness:project:')) {
2120
+ const slug = room.slice('harness:project:'.length);
2121
+ fileWatcherService.releaseHarnessWatcher({ scope: 'project', projectSlug: slug });
2122
+ }
2123
+ }
2124
+ socketHarnessRooms.delete(socket.id);
2125
+ }
1949
2126
  // Story 25.9: Cleanup summarizing state on disconnect
1950
2127
  const sumState = socketSummarizing.get(socket.id);
1951
2128
  if (sumState?.abortController) {
@@ -1981,6 +2158,31 @@ export function getIO() {
1981
2158
  }
1982
2159
  return io;
1983
2160
  }
2161
+ /**
2162
+ * Story 29.2 (AC1.e Phase 1): emit a fresh `snippets:list` payload to the
2163
+ * single socket that triggered a mutation, so the originating client's
2164
+ * SnippetPalette / useSnippets cache picks up the new state without an
2165
+ * explicit refresh round-trip.
2166
+ *
2167
+ * Phase-1 limitation: only the origin socket is notified. Other tabs / browsers
2168
+ * connected to the same project see stale data until their next user action
2169
+ * (panel open, page reload). The Phase-2 `project:${slug}` room fan-out is
2170
+ * deferred until ≥ 3 user reports of multi-tab divergence.
2171
+ *
2172
+ * Failures are swallowed — broadcast is best-effort and must not affect the
2173
+ * REST mutation's success/failure semantics.
2174
+ */
2175
+ export async function broadcastSnippetList(workingDirectory, originSocketId) {
2176
+ if (!workingDirectory || !originSocketId || !io)
2177
+ return;
2178
+ try {
2179
+ const snippets = await listSnippets(workingDirectory);
2180
+ io.to(originSocketId).emit('snippets:list', { snippets });
2181
+ }
2182
+ catch (err) {
2183
+ log.warn(`broadcastSnippetList failed for socket ${originSocketId}: ${String(err)}`);
2184
+ }
2185
+ }
1984
2186
  /**
1985
2187
  * Get the current number of connected clients
1986
2188
  * @returns Number of connected clients
@@ -2182,10 +2384,17 @@ async function handleChatSend(stream, data, abortController, lang) {
2182
2384
  stream.chatService = chatService;
2183
2385
  // Load preferences early for advanced settings + timeout
2184
2386
  const effectivePrefs = await preferencesService.getEffectivePreferences();
2185
- // Clamp 'max' effort to 'high' for non-Opus 4.6 models
2186
- const resolvedEffort = effort ?? effectivePrefs.defaultEffort;
2187
- const isOpus46 = model && (model === 'claude-opus-4-6' || model === 'opus' || model.includes('opus-4-6'));
2188
- const effectiveEffort = resolvedEffort === 'max' && !isOpus46 ? 'high' : resolvedEffort;
2387
+ const effectiveEffort = clampEffortForModel(effort ?? effectivePrefs.defaultEffort, model);
2388
+ // Opus 4.7 flipped `thinking.display` default to 'omitted' — ThinkingBlock UI stays blank
2389
+ // unless we explicitly opt in. For adaptive-thinking models, forward an explicit `thinking`
2390
+ // config based on the user's showThinkingBlocks preference (Hammoc default: true).
2391
+ // Legacy models (Sonnet 4.5, Opus 4.5, Haiku, Sonnet 4) keep the `maxThinkingTokens` path
2392
+ // since they don't accept `thinking.type: 'adaptive'`.
2393
+ const adaptiveCapable = supportsAdaptiveThinking(model);
2394
+ const showThinkingBlocks = effectivePrefs.showThinkingBlocks ?? true;
2395
+ const thinkingConfig = adaptiveCapable
2396
+ ? { type: 'adaptive', display: (showThinkingBlocks ? 'summarized' : 'omitted') }
2397
+ : undefined;
2189
2398
  const chatOptions = {
2190
2399
  ...(isResuming ? { resume: sessionId } : { sessionId }),
2191
2400
  abortController,
@@ -2193,7 +2402,11 @@ async function handleChatSend(stream, data, abortController, lang) {
2193
2402
  images,
2194
2403
  // Advanced settings from preferences
2195
2404
  customSystemPrompt: effectivePrefs.customSystemPrompt,
2196
- maxThinkingTokens: effectivePrefs.maxThinkingTokens,
2405
+ // maxThinkingTokens: legacy path; SDK docs say it takes precedence for backward-compat,
2406
+ // which conflicts with adaptive mode on Opus 4.7 (rejects enabled+budget). Skip on
2407
+ // adaptive-capable models so the explicit `thinking` field governs.
2408
+ ...(!adaptiveCapable && { maxThinkingTokens: effectivePrefs.maxThinkingTokens }),
2409
+ ...(thinkingConfig && { thinking: thinkingConfig }),
2197
2410
  maxTurns: effectivePrefs.maxTurns,
2198
2411
  maxBudgetUsd: effectivePrefs.maxBudgetUsd,
2199
2412
  effort: effectiveEffort,
@@ -2280,9 +2493,9 @@ async function handleChatSend(stream, data, abortController, lang) {
2280
2493
  };
2281
2494
  // Activity-based timeout: resets on every SDK callback event
2282
2495
  // Prevents cancellation while SDK is actively working (e.g., large Write input streaming)
2283
- // Timeout value from preferences (with env var override), clamped to 30s–30min range
2496
+ // Timeout value from preferences (with env var override), clamped to 5s–30min range
2284
2497
  const rawTimeoutMs = effectivePrefs.chatTimeoutMs ?? config.chat.timeoutMs;
2285
- const timeoutMs = (rawTimeoutMs >= 30000 && rawTimeoutMs <= 1800000) ? rawTimeoutMs : 300000;
2498
+ const timeoutMs = (rawTimeoutMs >= 5000 && rawTimeoutMs <= 1800000) ? rawTimeoutMs : 300000;
2286
2499
  let lastResetSource = 'initial';
2287
2500
  const resetTimeout = (source) => {
2288
2501
  if (source)