wave-agent-sdk 0.19.5 → 0.19.7

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 (371) hide show
  1. package/dist/agent.d.ts +30 -14
  2. package/dist/agent.js +70 -56
  3. package/dist/constants/goalPrompts.d.ts +0 -1
  4. package/dist/constants/subagents.d.ts +0 -1
  5. package/dist/constants/toolLimits.d.ts +0 -1
  6. package/dist/constants/tools.d.ts +0 -1
  7. package/dist/core/plugin.d.ts +0 -1
  8. package/dist/core/session.d.ts +0 -1
  9. package/dist/index.d.ts +0 -1
  10. package/dist/managers/MemoryRuleManager.d.ts +0 -1
  11. package/dist/managers/aiManager.d.ts +15 -2
  12. package/dist/managers/aiManager.js +65 -11
  13. package/dist/managers/backgroundTaskManager.d.ts +1 -3
  14. package/dist/managers/backgroundTaskManager.js +20 -22
  15. package/dist/managers/bangManager.d.ts +0 -1
  16. package/dist/managers/bangManager.js +2 -1
  17. package/dist/managers/cronManager.d.ts +0 -1
  18. package/dist/managers/foregroundTaskManager.d.ts +0 -1
  19. package/dist/managers/forkedAgentManager.d.ts +0 -1
  20. package/dist/managers/goalManager.d.ts +0 -1
  21. package/dist/managers/hookManager.d.ts +0 -1
  22. package/dist/managers/liveConfigManager.d.ts +0 -1
  23. package/dist/managers/lspManager.d.ts +0 -1
  24. package/dist/managers/mcpManager.d.ts +0 -1
  25. package/dist/managers/messageManager.d.ts +7 -1
  26. package/dist/managers/messageManager.js +64 -5
  27. package/dist/managers/messageQueue.d.ts +25 -2
  28. package/dist/managers/messageQueue.js +53 -1
  29. package/dist/managers/permissionManager.d.ts +0 -1
  30. package/dist/managers/permissionManager.js +3 -3
  31. package/dist/managers/planManager.d.ts +0 -1
  32. package/dist/managers/pluginManager.d.ts +0 -1
  33. package/dist/managers/pluginScopeManager.d.ts +0 -1
  34. package/dist/managers/reversionManager.d.ts +0 -1
  35. package/dist/managers/skillManager.d.ts +0 -1
  36. package/dist/managers/slashCommandManager.d.ts +0 -1
  37. package/dist/managers/subagentManager.d.ts +0 -3
  38. package/dist/managers/subagentManager.js +15 -14
  39. package/dist/managers/toolManager.d.ts +0 -1
  40. package/dist/managers/workflowManager.d.ts +1 -2
  41. package/dist/managers/workflowManager.js +4 -4
  42. package/dist/prompts/autoMemory.d.ts +0 -1
  43. package/dist/prompts/autoMemoryExtraction.d.ts +0 -1
  44. package/dist/prompts/index.d.ts +3 -2
  45. package/dist/prompts/index.js +2 -4
  46. package/dist/prompts/planModeReminders.d.ts +0 -1
  47. package/dist/services/GitService.d.ts +0 -1
  48. package/dist/services/MarketplaceService.d.ts +0 -1
  49. package/dist/services/MemoryRuleService.d.ts +0 -1
  50. package/dist/services/aiService.d.ts +0 -1
  51. package/dist/services/authService.d.ts +0 -1
  52. package/dist/services/autoMemoryService.d.ts +0 -1
  53. package/dist/services/configurationService.d.ts +0 -1
  54. package/dist/services/fileWatcher.d.ts +0 -1
  55. package/dist/services/hook.d.ts +0 -1
  56. package/dist/services/hook.js +6 -0
  57. package/dist/services/initializationService.d.ts +0 -1
  58. package/dist/services/interactionService.d.ts +0 -1
  59. package/dist/services/interactionService.js +10 -0
  60. package/dist/services/jsonlHandler.d.ts +0 -1
  61. package/dist/services/memory.d.ts +0 -1
  62. package/dist/services/pluginLoader.d.ts +0 -1
  63. package/dist/services/remoteSettingsService.d.ts +0 -1
  64. package/dist/services/reversionService.d.ts +0 -1
  65. package/dist/services/session.d.ts +0 -1
  66. package/dist/services/taskManager.d.ts +0 -1
  67. package/dist/services/taskManager.js +8 -1
  68. package/dist/telemetry/events.d.ts +0 -1
  69. package/dist/telemetry/instrumentation.d.ts +0 -1
  70. package/dist/telemetry/sessionTracing.d.ts +0 -1
  71. package/dist/tools/agentTool.d.ts +0 -1
  72. package/dist/tools/askUserQuestion.d.ts +0 -1
  73. package/dist/tools/bashTool.d.ts +0 -1
  74. package/dist/tools/bashTool.js +7 -5
  75. package/dist/tools/buildTool.d.ts +0 -1
  76. package/dist/tools/cronCreateTool.d.ts +0 -1
  77. package/dist/tools/cronDeleteTool.d.ts +0 -1
  78. package/dist/tools/cronListTool.d.ts +0 -1
  79. package/dist/tools/editTool.d.ts +0 -1
  80. package/dist/tools/enterPlanMode.d.ts +0 -1
  81. package/dist/tools/enterWorktreeTool.d.ts +0 -1
  82. package/dist/tools/enterWorktreeTool.js +3 -8
  83. package/dist/tools/exitPlanMode.d.ts +0 -1
  84. package/dist/tools/exitWorktreeTool.d.ts +0 -1
  85. package/dist/tools/exitWorktreeTool.js +5 -8
  86. package/dist/tools/globTool.d.ts +0 -1
  87. package/dist/tools/grepTool.d.ts +0 -1
  88. package/dist/tools/lspTool.d.ts +0 -1
  89. package/dist/tools/readTool.d.ts +0 -1
  90. package/dist/tools/skillTool.d.ts +0 -1
  91. package/dist/tools/taskManagementTools.d.ts +0 -1
  92. package/dist/tools/taskStopTool.d.ts +0 -1
  93. package/dist/tools/types.d.ts +0 -1
  94. package/dist/tools/webFetchTool.d.ts +0 -1
  95. package/dist/tools/workflowTool.d.ts +0 -1
  96. package/dist/tools/writeTool.d.ts +0 -1
  97. package/dist/types/agent.d.ts +0 -1
  98. package/dist/types/auth.d.ts +0 -1
  99. package/dist/types/commands.d.ts +0 -1
  100. package/dist/types/config.d.ts +0 -1
  101. package/dist/types/configuration.d.ts +0 -1
  102. package/dist/types/core.d.ts +0 -1
  103. package/dist/types/cron.d.ts +0 -1
  104. package/dist/types/environment.d.ts +0 -1
  105. package/dist/types/fileSearch.d.ts +0 -1
  106. package/dist/types/history.d.ts +0 -1
  107. package/dist/types/hooks.d.ts +2 -1
  108. package/dist/types/index.d.ts +0 -1
  109. package/dist/types/lsp.d.ts +0 -1
  110. package/dist/types/marketplace.d.ts +0 -1
  111. package/dist/types/mcp.d.ts +0 -1
  112. package/dist/types/memoryRule.d.ts +0 -1
  113. package/dist/types/messaging.d.ts +2 -1
  114. package/dist/types/permissions.d.ts +0 -1
  115. package/dist/types/plugins.d.ts +0 -1
  116. package/dist/types/processes.d.ts +0 -1
  117. package/dist/types/reversion.d.ts +0 -1
  118. package/dist/types/session.d.ts +0 -1
  119. package/dist/types/skills.d.ts +0 -1
  120. package/dist/types/tasks.d.ts +0 -1
  121. package/dist/types/telemetry.d.ts +0 -1
  122. package/dist/types/tools.d.ts +0 -1
  123. package/dist/types/workflow.d.ts +0 -1
  124. package/dist/utils/abortUtils.d.ts +0 -1
  125. package/dist/utils/atomicWrite.d.ts +0 -1
  126. package/dist/utils/bashParser.d.ts +0 -1
  127. package/dist/utils/cacheControlUtils.d.ts +0 -1
  128. package/dist/utils/commandArgumentParser.d.ts +0 -1
  129. package/dist/utils/commandPathResolver.d.ts +0 -1
  130. package/dist/utils/configPaths.d.ts +0 -1
  131. package/dist/utils/configValidator.d.ts +0 -1
  132. package/dist/utils/constants.d.ts +0 -1
  133. package/dist/utils/container.d.ts +0 -1
  134. package/dist/utils/containerSetup.d.ts +0 -1
  135. package/dist/utils/containerSetup.js +3 -3
  136. package/dist/utils/convertMessagesForAPI.d.ts +0 -1
  137. package/dist/utils/cronTasks.d.ts +0 -1
  138. package/dist/utils/cronTasksLock.d.ts +0 -1
  139. package/dist/utils/cronToHuman.d.ts +0 -1
  140. package/dist/utils/customCommands.d.ts +0 -1
  141. package/dist/utils/editUtils.d.ts +0 -1
  142. package/dist/utils/fileFormat.d.ts +0 -1
  143. package/dist/utils/fileSearch.d.ts +0 -1
  144. package/dist/utils/fileUtils.d.ts +0 -1
  145. package/dist/utils/gitUtils.d.ts +0 -1
  146. package/dist/utils/globalLogger.d.ts +0 -1
  147. package/dist/utils/groupMessagesByApiRound.d.ts +0 -1
  148. package/dist/utils/hookMatcher.d.ts +0 -1
  149. package/dist/utils/markdownParser.d.ts +0 -1
  150. package/dist/utils/mcpUtils.d.ts +0 -1
  151. package/dist/utils/messageOperations.d.ts +0 -1
  152. package/dist/utils/modelCapabilities.d.ts +0 -1
  153. package/dist/utils/nameGenerator.d.ts +0 -1
  154. package/dist/utils/notificationXml.d.ts +0 -1
  155. package/dist/utils/openaiClient.d.ts +0 -1
  156. package/dist/utils/parseCronExpression.d.ts +0 -1
  157. package/dist/utils/path.d.ts +0 -1
  158. package/dist/utils/pathEncoder.d.ts +0 -1
  159. package/dist/utils/pathSafety.d.ts +0 -1
  160. package/dist/utils/promptHistory.d.ts +0 -1
  161. package/dist/utils/ripgrep.d.ts +0 -1
  162. package/dist/utils/shellResolver.d.ts +0 -1
  163. package/dist/utils/shellResolver.js +156 -7
  164. package/dist/utils/skillParser.d.ts +0 -1
  165. package/dist/utils/stringUtils.d.ts +0 -1
  166. package/dist/utils/subagentParser.d.ts +0 -1
  167. package/dist/utils/taskReminder.d.ts +0 -1
  168. package/dist/utils/tokenCalculation.d.ts +0 -1
  169. package/dist/utils/tokenEstimate.d.ts +0 -1
  170. package/dist/utils/toolResultStorage.d.ts +0 -1
  171. package/dist/utils/worktreeSession.d.ts +6 -7
  172. package/dist/utils/worktreeSession.js +7 -11
  173. package/dist/utils/worktreeUtils.d.ts +0 -1
  174. package/dist/workflow/budgetTracker.d.ts +0 -1
  175. package/dist/workflow/concurrencyLimiter.d.ts +0 -1
  176. package/dist/workflow/journal.d.ts +0 -1
  177. package/dist/workflow/progressReporter.d.ts +0 -1
  178. package/dist/workflow/runState.d.ts +0 -1
  179. package/dist/workflow/scriptRuntime.d.ts +0 -1
  180. package/dist/workflow/structuredOutput.d.ts +0 -1
  181. package/dist/workflow/types.d.ts +0 -1
  182. package/dist/workflow/workflowApis.d.ts +0 -1
  183. package/package.json +1 -1
  184. package/src/agent.ts +80 -67
  185. package/src/managers/aiManager.ts +79 -12
  186. package/src/managers/backgroundTaskManager.ts +21 -23
  187. package/src/managers/bangManager.ts +2 -1
  188. package/src/managers/messageManager.ts +72 -6
  189. package/src/managers/messageQueue.ts +60 -2
  190. package/src/managers/permissionManager.ts +6 -3
  191. package/src/managers/subagentManager.ts +22 -16
  192. package/src/managers/workflowManager.ts +5 -5
  193. package/src/prompts/index.ts +4 -4
  194. package/src/services/hook.ts +9 -0
  195. package/src/services/interactionService.ts +11 -0
  196. package/src/services/taskManager.ts +8 -1
  197. package/src/tools/bashTool.ts +11 -5
  198. package/src/tools/enterWorktreeTool.ts +4 -14
  199. package/src/tools/exitWorktreeTool.ts +5 -13
  200. package/src/types/hooks.ts +2 -0
  201. package/src/types/messaging.ts +2 -0
  202. package/src/utils/containerSetup.ts +3 -3
  203. package/src/utils/shellResolver.ts +167 -8
  204. package/src/utils/worktreeSession.ts +6 -16
  205. package/dist/agent.d.ts.map +0 -1
  206. package/dist/constants/goalPrompts.d.ts.map +0 -1
  207. package/dist/constants/subagents.d.ts.map +0 -1
  208. package/dist/constants/toolLimits.d.ts.map +0 -1
  209. package/dist/constants/tools.d.ts.map +0 -1
  210. package/dist/core/plugin.d.ts.map +0 -1
  211. package/dist/core/session.d.ts.map +0 -1
  212. package/dist/index.d.ts.map +0 -1
  213. package/dist/managers/MemoryRuleManager.d.ts.map +0 -1
  214. package/dist/managers/aiManager.d.ts.map +0 -1
  215. package/dist/managers/backgroundTaskManager.d.ts.map +0 -1
  216. package/dist/managers/bangManager.d.ts.map +0 -1
  217. package/dist/managers/cronManager.d.ts.map +0 -1
  218. package/dist/managers/foregroundTaskManager.d.ts.map +0 -1
  219. package/dist/managers/forkedAgentManager.d.ts.map +0 -1
  220. package/dist/managers/goalManager.d.ts.map +0 -1
  221. package/dist/managers/hookManager.d.ts.map +0 -1
  222. package/dist/managers/liveConfigManager.d.ts.map +0 -1
  223. package/dist/managers/lspManager.d.ts.map +0 -1
  224. package/dist/managers/mcpManager.d.ts.map +0 -1
  225. package/dist/managers/messageManager.d.ts.map +0 -1
  226. package/dist/managers/messageQueue.d.ts.map +0 -1
  227. package/dist/managers/notificationQueue.d.ts +0 -8
  228. package/dist/managers/notificationQueue.d.ts.map +0 -1
  229. package/dist/managers/notificationQueue.js +0 -17
  230. package/dist/managers/permissionManager.d.ts.map +0 -1
  231. package/dist/managers/planManager.d.ts.map +0 -1
  232. package/dist/managers/pluginManager.d.ts.map +0 -1
  233. package/dist/managers/pluginScopeManager.d.ts.map +0 -1
  234. package/dist/managers/reversionManager.d.ts.map +0 -1
  235. package/dist/managers/skillManager.d.ts.map +0 -1
  236. package/dist/managers/slashCommandManager.d.ts.map +0 -1
  237. package/dist/managers/subagentManager.d.ts.map +0 -1
  238. package/dist/managers/toolManager.d.ts.map +0 -1
  239. package/dist/managers/workflowManager.d.ts.map +0 -1
  240. package/dist/prompts/autoMemory.d.ts.map +0 -1
  241. package/dist/prompts/autoMemoryExtraction.d.ts.map +0 -1
  242. package/dist/prompts/index.d.ts.map +0 -1
  243. package/dist/prompts/planModeReminders.d.ts.map +0 -1
  244. package/dist/services/GitService.d.ts.map +0 -1
  245. package/dist/services/MarketplaceService.d.ts.map +0 -1
  246. package/dist/services/MemoryRuleService.d.ts.map +0 -1
  247. package/dist/services/aiService.d.ts.map +0 -1
  248. package/dist/services/authService.d.ts.map +0 -1
  249. package/dist/services/autoMemoryService.d.ts.map +0 -1
  250. package/dist/services/configurationService.d.ts.map +0 -1
  251. package/dist/services/fileWatcher.d.ts.map +0 -1
  252. package/dist/services/hook.d.ts.map +0 -1
  253. package/dist/services/initializationService.d.ts.map +0 -1
  254. package/dist/services/interactionService.d.ts.map +0 -1
  255. package/dist/services/jsonlHandler.d.ts.map +0 -1
  256. package/dist/services/memory.d.ts.map +0 -1
  257. package/dist/services/pluginLoader.d.ts.map +0 -1
  258. package/dist/services/remoteSettingsService.d.ts.map +0 -1
  259. package/dist/services/reversionService.d.ts.map +0 -1
  260. package/dist/services/session.d.ts.map +0 -1
  261. package/dist/services/taskManager.d.ts.map +0 -1
  262. package/dist/telemetry/events.d.ts.map +0 -1
  263. package/dist/telemetry/instrumentation.d.ts.map +0 -1
  264. package/dist/telemetry/sessionTracing.d.ts.map +0 -1
  265. package/dist/tools/agentTool.d.ts.map +0 -1
  266. package/dist/tools/askUserQuestion.d.ts.map +0 -1
  267. package/dist/tools/bashTool.d.ts.map +0 -1
  268. package/dist/tools/buildTool.d.ts.map +0 -1
  269. package/dist/tools/cronCreateTool.d.ts.map +0 -1
  270. package/dist/tools/cronDeleteTool.d.ts.map +0 -1
  271. package/dist/tools/cronListTool.d.ts.map +0 -1
  272. package/dist/tools/editTool.d.ts.map +0 -1
  273. package/dist/tools/enterPlanMode.d.ts.map +0 -1
  274. package/dist/tools/enterWorktreeTool.d.ts.map +0 -1
  275. package/dist/tools/exitPlanMode.d.ts.map +0 -1
  276. package/dist/tools/exitWorktreeTool.d.ts.map +0 -1
  277. package/dist/tools/globTool.d.ts.map +0 -1
  278. package/dist/tools/grepTool.d.ts.map +0 -1
  279. package/dist/tools/lspTool.d.ts.map +0 -1
  280. package/dist/tools/readTool.d.ts.map +0 -1
  281. package/dist/tools/skillTool.d.ts.map +0 -1
  282. package/dist/tools/taskManagementTools.d.ts.map +0 -1
  283. package/dist/tools/taskStopTool.d.ts.map +0 -1
  284. package/dist/tools/types.d.ts.map +0 -1
  285. package/dist/tools/webFetchTool.d.ts.map +0 -1
  286. package/dist/tools/workflowTool.d.ts.map +0 -1
  287. package/dist/tools/writeTool.d.ts.map +0 -1
  288. package/dist/types/agent.d.ts.map +0 -1
  289. package/dist/types/auth.d.ts.map +0 -1
  290. package/dist/types/commands.d.ts.map +0 -1
  291. package/dist/types/config.d.ts.map +0 -1
  292. package/dist/types/configuration.d.ts.map +0 -1
  293. package/dist/types/core.d.ts.map +0 -1
  294. package/dist/types/cron.d.ts.map +0 -1
  295. package/dist/types/environment.d.ts.map +0 -1
  296. package/dist/types/fileSearch.d.ts.map +0 -1
  297. package/dist/types/history.d.ts.map +0 -1
  298. package/dist/types/hooks.d.ts.map +0 -1
  299. package/dist/types/index.d.ts.map +0 -1
  300. package/dist/types/lsp.d.ts.map +0 -1
  301. package/dist/types/marketplace.d.ts.map +0 -1
  302. package/dist/types/mcp.d.ts.map +0 -1
  303. package/dist/types/memoryRule.d.ts.map +0 -1
  304. package/dist/types/messaging.d.ts.map +0 -1
  305. package/dist/types/permissions.d.ts.map +0 -1
  306. package/dist/types/plugins.d.ts.map +0 -1
  307. package/dist/types/processes.d.ts.map +0 -1
  308. package/dist/types/reversion.d.ts.map +0 -1
  309. package/dist/types/session.d.ts.map +0 -1
  310. package/dist/types/skills.d.ts.map +0 -1
  311. package/dist/types/tasks.d.ts.map +0 -1
  312. package/dist/types/telemetry.d.ts.map +0 -1
  313. package/dist/types/tools.d.ts.map +0 -1
  314. package/dist/types/workflow.d.ts.map +0 -1
  315. package/dist/utils/abortUtils.d.ts.map +0 -1
  316. package/dist/utils/atomicWrite.d.ts.map +0 -1
  317. package/dist/utils/bashParser.d.ts.map +0 -1
  318. package/dist/utils/cacheControlUtils.d.ts.map +0 -1
  319. package/dist/utils/commandArgumentParser.d.ts.map +0 -1
  320. package/dist/utils/commandPathResolver.d.ts.map +0 -1
  321. package/dist/utils/configPaths.d.ts.map +0 -1
  322. package/dist/utils/configValidator.d.ts.map +0 -1
  323. package/dist/utils/constants.d.ts.map +0 -1
  324. package/dist/utils/container.d.ts.map +0 -1
  325. package/dist/utils/containerSetup.d.ts.map +0 -1
  326. package/dist/utils/convertMessagesForAPI.d.ts.map +0 -1
  327. package/dist/utils/cronTasks.d.ts.map +0 -1
  328. package/dist/utils/cronTasksLock.d.ts.map +0 -1
  329. package/dist/utils/cronToHuman.d.ts.map +0 -1
  330. package/dist/utils/customCommands.d.ts.map +0 -1
  331. package/dist/utils/editUtils.d.ts.map +0 -1
  332. package/dist/utils/fileFormat.d.ts.map +0 -1
  333. package/dist/utils/fileSearch.d.ts.map +0 -1
  334. package/dist/utils/fileUtils.d.ts.map +0 -1
  335. package/dist/utils/gitUtils.d.ts.map +0 -1
  336. package/dist/utils/globalLogger.d.ts.map +0 -1
  337. package/dist/utils/groupMessagesByApiRound.d.ts.map +0 -1
  338. package/dist/utils/hookMatcher.d.ts.map +0 -1
  339. package/dist/utils/markdownParser.d.ts.map +0 -1
  340. package/dist/utils/mcpUtils.d.ts.map +0 -1
  341. package/dist/utils/messageOperations.d.ts.map +0 -1
  342. package/dist/utils/modelCapabilities.d.ts.map +0 -1
  343. package/dist/utils/nameGenerator.d.ts.map +0 -1
  344. package/dist/utils/notificationXml.d.ts.map +0 -1
  345. package/dist/utils/openaiClient.d.ts.map +0 -1
  346. package/dist/utils/parseCronExpression.d.ts.map +0 -1
  347. package/dist/utils/path.d.ts.map +0 -1
  348. package/dist/utils/pathEncoder.d.ts.map +0 -1
  349. package/dist/utils/pathSafety.d.ts.map +0 -1
  350. package/dist/utils/promptHistory.d.ts.map +0 -1
  351. package/dist/utils/ripgrep.d.ts.map +0 -1
  352. package/dist/utils/shellResolver.d.ts.map +0 -1
  353. package/dist/utils/skillParser.d.ts.map +0 -1
  354. package/dist/utils/stringUtils.d.ts.map +0 -1
  355. package/dist/utils/subagentParser.d.ts.map +0 -1
  356. package/dist/utils/taskReminder.d.ts.map +0 -1
  357. package/dist/utils/tokenCalculation.d.ts.map +0 -1
  358. package/dist/utils/tokenEstimate.d.ts.map +0 -1
  359. package/dist/utils/toolResultStorage.d.ts.map +0 -1
  360. package/dist/utils/worktreeSession.d.ts.map +0 -1
  361. package/dist/utils/worktreeUtils.d.ts.map +0 -1
  362. package/dist/workflow/budgetTracker.d.ts.map +0 -1
  363. package/dist/workflow/concurrencyLimiter.d.ts.map +0 -1
  364. package/dist/workflow/journal.d.ts.map +0 -1
  365. package/dist/workflow/progressReporter.d.ts.map +0 -1
  366. package/dist/workflow/runState.d.ts.map +0 -1
  367. package/dist/workflow/scriptRuntime.d.ts.map +0 -1
  368. package/dist/workflow/structuredOutput.d.ts.map +0 -1
  369. package/dist/workflow/types.d.ts.map +0 -1
  370. package/dist/workflow/workflowApis.d.ts.map +0 -1
  371. package/src/managers/notificationQueue.ts +0 -19
@@ -16,7 +16,7 @@ import {
16
16
  type AddNotificationMessageParams,
17
17
  generateMessageId,
18
18
  } from "../utils/messageOperations.js";
19
- import type { Message, Usage } from "../types/index.js";
19
+ import type { Message, Usage, ToolBlock } from "../types/index.js";
20
20
  import { getLastApiRounds } from "../utils/groupMessagesByApiRound.js";
21
21
  import { join, isAbsolute, relative } from "path";
22
22
  import {
@@ -718,12 +718,23 @@ export class MessageManager {
718
718
  type: "text" | "reasoning";
719
719
  content: string;
720
720
  stage?: string;
721
+ startTime?: number;
721
722
  };
722
- lastMessage.blocks[index] = {
723
- type: block.type,
724
- content: block.content,
725
- stage: "end" as const,
726
- };
723
+ if (block.type === "reasoning") {
724
+ lastMessage.blocks[index] = {
725
+ type: "reasoning",
726
+ content: block.content,
727
+ stage: "end" as const,
728
+ startTime: block.startTime,
729
+ endTime: Date.now(),
730
+ };
731
+ } else {
732
+ lastMessage.blocks[index] = {
733
+ type: block.type,
734
+ content: block.content,
735
+ stage: "end" as const,
736
+ };
737
+ }
727
738
 
728
739
  // Fire incremental callback to signal finalization
729
740
  const callbackParams = {
@@ -832,10 +843,16 @@ export class MessageManager {
832
843
 
833
844
  if (reasoningBlockIndex >= 0) {
834
845
  // Update existing reasoning block
846
+ const existingStartTime = (
847
+ lastMessage.blocks[reasoningBlockIndex] as {
848
+ startTime?: number;
849
+ }
850
+ ).startTime;
835
851
  lastMessage.blocks[reasoningBlockIndex] = {
836
852
  type: "reasoning",
837
853
  content: newAccumulatedReasoning,
838
854
  stage: "streaming",
855
+ startTime: existingStartTime,
839
856
  };
840
857
  } else {
841
858
  // Add new reasoning block if none exists
@@ -843,6 +860,7 @@ export class MessageManager {
843
860
  type: "reasoning",
844
861
  content: newAccumulatedReasoning,
845
862
  stage: "streaming",
863
+ startTime: Date.now(),
846
864
  });
847
865
  }
848
866
 
@@ -878,6 +896,54 @@ export class MessageManager {
878
896
  }
879
897
  }
880
898
 
899
+ /**
900
+ * Finalize any tool blocks still in a non-terminal stage (start/streaming/running)
901
+ * by marking them as ended with an error. Called when the AI call is aborted or
902
+ * fails mid-tool-stream so the UI stops showing the "running" spinner.
903
+ * Fires onToolBlockUpdated for each finalized tool block.
904
+ */
905
+ public finalizeAbortedToolBlocks(error?: string): void {
906
+ if (this.messages.length === 0) return;
907
+ const lastMessage = this.messages[this.messages.length - 1];
908
+ if (lastMessage.role !== "assistant") return;
909
+
910
+ const errorMessage = error ?? "Tool execution was aborted";
911
+ let finalized = false;
912
+
913
+ for (let i = 0; i < lastMessage.blocks.length; i++) {
914
+ const block = lastMessage.blocks[i] as ToolBlock;
915
+ if (block.type !== "tool" || block.stage === "end") continue;
916
+
917
+ const timestamp = Date.now();
918
+ lastMessage.blocks[i] = {
919
+ ...block,
920
+ stage: "end",
921
+ success: false,
922
+ error: errorMessage,
923
+ timestamp,
924
+ };
925
+ finalized = true;
926
+
927
+ this.callbacks.onToolBlockUpdated?.({
928
+ id: block.id ?? "",
929
+ messageId: lastMessage.id ?? "",
930
+ name: block.name,
931
+ parameters: block.parameters,
932
+ parametersChunk: block.parametersChunk,
933
+ compactParams: block.compactParams,
934
+ stage: "end",
935
+ success: false,
936
+ error: errorMessage,
937
+ isManuallyBackgrounded: block.isManuallyBackgrounded,
938
+ timestamp,
939
+ });
940
+ }
941
+
942
+ if (finalized) {
943
+ this.setMessages([...this.messages]);
944
+ }
945
+ }
946
+
881
947
  /**
882
948
  * Remove the last user message from the conversation
883
949
  * Used for hook error handling when the user prompt needs to be erased
@@ -2,7 +2,7 @@ export type QueueState = "idle" | "dispatching" | "running";
2
2
 
3
3
  export interface QueuedMessage {
4
4
  id?: string;
5
- type?: "message" | "bang";
5
+ type?: "message" | "bang" | "notification";
6
6
  content: string;
7
7
  images?: Array<{ path: string; mimeType: string }>;
8
8
  longTextMap?: Record<string, string>;
@@ -44,8 +44,12 @@ export class MessageQueue {
44
44
  return this.queue.shift() ?? null;
45
45
  }
46
46
 
47
+ /**
48
+ * Clear user-facing items (messages, bang commands) but preserve pending
49
+ * notifications so background task results are not lost on abort.
50
+ */
47
51
  clear(): void {
48
- this.queue = [];
52
+ this.queue = this.queue.filter((m) => m.type === "notification");
49
53
  this._state = "idle";
50
54
  }
51
55
 
@@ -74,6 +78,23 @@ export class MessageQueue {
74
78
  return true;
75
79
  }
76
80
 
81
+ updateById(
82
+ id: string,
83
+ patch: {
84
+ content?: string;
85
+ images?: Array<{ path: string; mimeType: string }>;
86
+ type?: "message" | "bang";
87
+ },
88
+ ): boolean {
89
+ const m = this.queue.find((x) => x.id === id);
90
+ if (!m) return false;
91
+ if (patch.content !== undefined) m.content = patch.content;
92
+ if (patch.images !== undefined) m.images = patch.images;
93
+ if (patch.type !== undefined) m.type = patch.type;
94
+ this.onMessageEnqueued?.();
95
+ return true;
96
+ }
97
+
77
98
  popLastEditable(): QueuedMessage | null {
78
99
  for (let i = this.queue.length - 1; i >= 0; i--) {
79
100
  if (this.queue[i].editable !== false) {
@@ -96,4 +117,41 @@ export class MessageQueue {
96
117
  this.queue = remaining;
97
118
  return editable;
98
119
  }
120
+
121
+ /**
122
+ * Enqueue a background task notification (XML string). Notifications are
123
+ * not user-editable and not surfaced in the queued-messages UI.
124
+ */
125
+ enqueueNotification(xml: string): void {
126
+ this.queue.push({
127
+ id: `mq-${this.nextId++}`,
128
+ type: "notification",
129
+ content: xml,
130
+ editable: false,
131
+ });
132
+ this.onMessageEnqueued?.();
133
+ }
134
+
135
+ /** Whether any notification items are pending. */
136
+ hasNotifications(): boolean {
137
+ return this.queue.some((m) => m.type === "notification");
138
+ }
139
+
140
+ /**
141
+ * Drain all notification items, returning their XML content. Non-notification
142
+ * items (messages, bang commands) are preserved in the queue.
143
+ */
144
+ drainNotifications(): string[] {
145
+ const notifications: string[] = [];
146
+ const remaining: QueuedMessage[] = [];
147
+ for (const msg of this.queue) {
148
+ if (msg.type === "notification") {
149
+ notifications.push(msg.content);
150
+ } else {
151
+ remaining.push(msg);
152
+ }
153
+ }
154
+ this.queue = remaining;
155
+ return notifications;
156
+ }
99
157
  }
@@ -35,7 +35,7 @@ import {
35
35
  } from "../constants/tools.js";
36
36
  import { Container } from "../utils/container.js";
37
37
  import { ConfigurationService } from "../services/configurationService.js";
38
- import { getCurrentWorktreeSession } from "../utils/worktreeSession.js";
38
+ import type { WorktreeSession } from "../utils/worktreeSession.js";
39
39
 
40
40
  const SAFE_COMMANDS = [
41
41
  "cd",
@@ -452,8 +452,11 @@ export class PermissionManager {
452
452
  }
453
453
 
454
454
  // 1.0 Check worktree safety for Write and Edit tools
455
- // Support both CLI -w sessions (container-registered) and EnterWorktree mid-session (module-level)
456
- const worktreeSession = getCurrentWorktreeSession();
455
+ // Support both CLI -w sessions (container-registered) and EnterWorktree mid-session
456
+ // (per-agent WorktreeSession stored in this session's container)
457
+ const worktreeSession = this.container.get<WorktreeSession | null>(
458
+ "WorktreeSession",
459
+ );
457
460
  const effectiveWorktreeName =
458
461
  this.worktreeName || worktreeSession?.worktreeName;
459
462
  const effectiveWorkdir = this.workdir || worktreeSession?.worktreePath;
@@ -7,13 +7,19 @@ import type { Message, Usage } from "../types/index.js";
7
7
  import { AIManager } from "./aiManager.js";
8
8
  import { MessageManager } from "./messageManager.js";
9
9
  import { ToolManager } from "./toolManager.js";
10
- import { AGENT_TOOL_NAME } from "../constants/tools.js";
10
+ import {
11
+ AGENT_TOOL_NAME,
12
+ TASK_CREATE_TOOL_NAME,
13
+ TASK_GET_TOOL_NAME,
14
+ TASK_LIST_TOOL_NAME,
15
+ TASK_UPDATE_TOOL_NAME,
16
+ } from "../constants/tools.js";
11
17
  import {
12
18
  addConsolidatedAbortListener,
13
19
  createAbortPromise,
14
20
  } from "../utils/abortUtils.js";
15
21
  import { BackgroundTaskManager } from "./backgroundTaskManager.js";
16
- import { NotificationQueue } from "./notificationQueue.js";
22
+ import { MessageQueue } from "./messageQueue.js";
17
23
  import { logger } from "../utils/globalLogger.js";
18
24
  import {
19
25
  UserMessageParams,
@@ -75,7 +81,6 @@ export interface SubagentInstance {
75
81
  toolManager: ToolManager;
76
82
  permissionManager: PermissionManager;
77
83
  backgroundTaskManager: BackgroundTaskManager;
78
- notificationQueue: NotificationQueue;
79
84
  status: "initializing" | "active" | "completed" | "error" | "aborted";
80
85
  messages: Message[];
81
86
  usedTools: {
@@ -321,6 +326,12 @@ export class SubagentManager {
321
326
  instanceDeniedRules: [
322
327
  ...(parentPermissionManager?.getInstanceDeniedRules?.() || []),
323
328
  AGENT_TOOL_NAME, // Always deny Agent tool in subagents to prevent recursion
329
+ // Deny Task tools in subagents — they share the parent's TaskManager
330
+ // and could mutate the main agent's task list
331
+ TASK_CREATE_TOOL_NAME,
332
+ TASK_GET_TOOL_NAME,
333
+ TASK_UPDATE_TOOL_NAME,
334
+ TASK_LIST_TOOL_NAME,
324
335
  ],
325
336
  additionalDirectories:
326
337
  parentPermissionManager?.getAdditionalDirectories(),
@@ -381,10 +392,6 @@ export class SubagentManager {
381
392
  });
382
393
  subagentContainer.register("AIManager", aiManager);
383
394
 
384
- // Create isolated NotificationQueue for the subagent/forked agent
385
- const subagentNotificationQueue = new NotificationQueue();
386
- subagentContainer.register("NotificationQueue", subagentNotificationQueue);
387
-
388
395
  // Create isolated BackgroundTaskManager for the subagent/forked agent
389
396
  const subagentBackgroundTaskManager = new BackgroundTaskManager(
390
397
  subagentContainer,
@@ -405,7 +412,6 @@ export class SubagentManager {
405
412
  toolManager,
406
413
  permissionManager: subagentPermissionManager,
407
414
  backgroundTaskManager: subagentBackgroundTaskManager,
408
- notificationQueue: subagentNotificationQueue,
409
415
  status: "initializing",
410
416
  messages: [],
411
417
  usedTools: [], // Initialize usedTools
@@ -645,12 +651,12 @@ export class SubagentManager {
645
651
  }
646
652
  // Skip notification if task was already stopped (e.g. by main agent shutdown)
647
653
  if (!wasAlreadyKilled) {
648
- const notificationQueue = this.container.has("NotificationQueue")
649
- ? this.container.get<NotificationQueue>("NotificationQueue")
654
+ const messageQueue = this.container.has("MessageQueue")
655
+ ? this.container.get<MessageQueue>("MessageQueue")
650
656
  : undefined;
651
- if (notificationQueue) {
657
+ if (messageQueue) {
652
658
  const summary = `Agent task "${instance.description}" completed`;
653
- notificationQueue.enqueue(
659
+ messageQueue.enqueueNotification(
654
660
  `<task-notification>\n<task-id>${instance.backgroundTaskId}</task-id>\n<task-type>agent</task-type>\n<status>completed</status>\n<summary>${summary}</summary>\n</task-notification>`,
655
661
  );
656
662
  }
@@ -682,14 +688,14 @@ export class SubagentManager {
682
688
  }
683
689
  // Skip notification if task was already stopped (e.g. by main agent shutdown)
684
690
  if (!wasAlreadyKilled) {
685
- const notificationQueue = this.container.has("NotificationQueue")
686
- ? this.container.get<NotificationQueue>("NotificationQueue")
691
+ const messageQueue = this.container.has("MessageQueue")
692
+ ? this.container.get<MessageQueue>("MessageQueue")
687
693
  : undefined;
688
- if (notificationQueue) {
694
+ if (messageQueue) {
689
695
  const errorMsg =
690
696
  error instanceof Error ? error.message : String(error);
691
697
  const summary = `Agent task "${instance.description}" failed: ${errorMsg}`;
692
- notificationQueue.enqueue(
698
+ messageQueue.enqueueNotification(
693
699
  `<task-notification>\n<task-id>${instance.backgroundTaskId}</task-id>\n<task-type>agent</task-type>\n<status>failed</status>\n<summary>${summary}</summary>\n</task-notification>`,
694
700
  );
695
701
  }
@@ -4,7 +4,7 @@ import * as fs from "fs";
4
4
  import * as path from "path";
5
5
  import { Container } from "../utils/container.js";
6
6
  import { BackgroundTaskManager } from "./backgroundTaskManager.js";
7
- import { NotificationQueue } from "./notificationQueue.js";
7
+ import { MessageQueue } from "./messageQueue.js";
8
8
  import { SubagentManager } from "./subagentManager.js";
9
9
  import { taskNotificationToXml } from "../utils/notificationXml.js";
10
10
  import { ConcurrencyLimiter } from "../workflow/concurrencyLimiter.js";
@@ -49,8 +49,8 @@ export class WorkflowManager {
49
49
  return this.container.get<BackgroundTaskManager>("BackgroundTaskManager")!;
50
50
  }
51
51
 
52
- private get notificationQueue(): NotificationQueue {
53
- return this.container.get<NotificationQueue>("NotificationQueue")!;
52
+ private get messageQueue(): MessageQueue {
53
+ return this.container.get<MessageQueue>("MessageQueue")!;
54
54
  }
55
55
 
56
56
  private get subagentManager(): SubagentManager {
@@ -295,7 +295,7 @@ export class WorkflowManager {
295
295
 
296
296
  // Enqueue completion notification
297
297
  const journalPath = journal.filePath;
298
- this.notificationQueue.enqueue(
298
+ this.messageQueue.enqueueNotification(
299
299
  taskNotificationToXml({
300
300
  type: "task_notification",
301
301
  taskId: runId,
@@ -337,7 +337,7 @@ export class WorkflowManager {
337
337
  task.endTime = Date.now();
338
338
  }
339
339
 
340
- this.notificationQueue.enqueue(
340
+ this.messageQueue.enqueueNotification(
341
341
  taskNotificationToXml({
342
342
  type: "task_notification",
343
343
  taskId: runId,
@@ -1,7 +1,7 @@
1
1
  import * as os from "node:os";
2
2
  import { ToolPlugin } from "../tools/types.js";
3
3
  import { isGitRepository } from "../utils/gitUtils.js";
4
- import { getCurrentWorktreeSession } from "../utils/worktreeSession.js";
4
+ import type { WorktreeSession } from "../utils/worktreeSession.js";
5
5
  import { buildAutoMemoryPrompt } from "./autoMemory.js";
6
6
  import {
7
7
  EXPLORE_SUBAGENT_TYPE,
@@ -252,6 +252,7 @@ export function buildSystemPrompt(
252
252
  originalWorkdir?: string;
253
253
  language?: string;
254
254
  isSubagent?: boolean;
255
+ worktreeSession?: WorktreeSession | null;
255
256
  autoMemory?: {
256
257
  directory: string;
257
258
  content: string;
@@ -292,7 +293,7 @@ export function buildSystemPrompt(
292
293
  ? "bash"
293
294
  : shell;
294
295
 
295
- const worktreeSession = getCurrentWorktreeSession();
296
+ const worktreeSession = options.worktreeSession;
296
297
 
297
298
  dynamicText += `
298
299
 
@@ -326,6 +327,7 @@ export function enhanceSystemPromptWithEnvDetails(
326
327
  existingSystemPrompt: string,
327
328
  workdir: string,
328
329
  originalWorkdir?: string,
330
+ worktreeSession?: WorktreeSession | null,
329
331
  ): string {
330
332
  const isGitRepo = isGitRepository(workdir);
331
333
  const platform = os.platform();
@@ -338,8 +340,6 @@ export function enhanceSystemPromptWithEnvDetails(
338
340
  ? "bash"
339
341
  : shell;
340
342
 
341
- const worktreeSession = getCurrentWorktreeSession();
342
-
343
343
  const notes = `Notes:
344
344
  - Agent threads always have their cwd reset between bash calls, as a result please only use absolute file paths.${worktreeSession ? `\n- You are in a git worktree at ${worktreeSession.worktreePath} (branch: ${worktreeSession.worktreeBranch}). Absolute paths from prior context may refer to the original repo at ${worktreeSession.originalCwd}; translate them to your worktree. Do NOT edit files outside this worktree.` : ""}
345
345
  - In your final response, share file paths (always absolute, never relative) that are relevant to the task. Include code snippets only when the exact text is load-bearing (e.g., a bug you found, a function signature the caller asked for) — do not recap code you merely read.
@@ -120,6 +120,15 @@ async function buildHookJsonInput(
120
120
  jsonInput.session_crons = context.sessionCrons ?? [];
121
121
  }
122
122
 
123
+ // Add last_assistant_message for Stop and SubagentStop events.
124
+ // Omitted when undefined (no text content in last assistant message).
125
+ if (
126
+ (context.event === "Stop" || context.event === "SubagentStop") &&
127
+ context.lastAssistantMessage !== undefined
128
+ ) {
129
+ jsonInput.last_assistant_message = context.lastAssistantMessage;
130
+ }
131
+
123
132
  return jsonInput;
124
133
  }
125
134
 
@@ -71,6 +71,13 @@ export class InteractionService {
71
71
  })),
72
72
  });
73
73
 
74
+ // Reserve loading state synchronously before any async work (hooks).
75
+ // This closes the race window where a concurrent notification/message
76
+ // could see isLoading=false during the await below and start a second
77
+ // sendAIMessage. sendAIMessage's generation guard is the backstop, but
78
+ // reserving here prevents the race at its source.
79
+ aiManager.setIsLoading(true);
80
+
74
81
  // Execute UserPromptSubmit hooks after adding the user message
75
82
  if (hookManager) {
76
83
  try {
@@ -104,6 +111,8 @@ export class InteractionService {
104
111
  "UserPromptSubmit hook blocked prompt processing with error:",
105
112
  processResult.errorMessage,
106
113
  );
114
+ // Release the loading state we reserved above
115
+ aiManager.setIsLoading(false);
107
116
  return; // Don't send to AI
108
117
  }
109
118
  } catch (error) {
@@ -116,6 +125,8 @@ export class InteractionService {
116
125
  await aiManager.sendAIMessage();
117
126
  } catch (error) {
118
127
  console.error("Failed to add user message:", error);
128
+ // Ensure loading state is released on error
129
+ aiManager.setIsLoading(false);
119
130
  // Loading state will be automatically updated by the useEffect that watches messages
120
131
  }
121
132
  }
@@ -7,6 +7,13 @@ import { logger } from "../utils/globalLogger.js";
7
7
  import { Container } from "../utils/container.js";
8
8
  import type { MessageManager } from "../managers/messageManager.js";
9
9
 
10
+ function byIdAsc(a: Task, b: Task) {
11
+ const aNum = parseInt(a.id, 10);
12
+ const bNum = parseInt(b.id, 10);
13
+ if (!isNaN(aNum) && !isNaN(bNum)) return aNum - bNum;
14
+ return a.id.localeCompare(b.id);
15
+ }
16
+
10
17
  export class TaskManager extends EventEmitter {
11
18
  private readonly baseDir: string;
12
19
  private taskListId: string;
@@ -234,7 +241,7 @@ export class TaskManager extends EventEmitter {
234
241
  }),
235
242
  );
236
243
 
237
- return tasks.filter((t): t is Task => t !== null);
244
+ return tasks.filter((t): t is Task => t !== null).sort(byIdAsc);
238
245
  } catch (error) {
239
246
  if ((error as NodeJS.ErrnoException).code === "ENOENT") {
240
247
  return [];
@@ -173,14 +173,16 @@ The working directory persists between commands. Try to maintain your current wo
173
173
  };
174
174
  }
175
175
 
176
- // Resolve shell path: on Windows, use Git Bash; on other platforms, use default
176
+ // Resolve shell path: on Windows, use Git Bash; on macOS/Linux, use bash or zsh
177
177
  const shellPath = resolveShellPath();
178
- if (process.platform === "win32" && !shellPath) {
178
+ if (!shellPath) {
179
179
  return {
180
180
  success: false,
181
181
  content: "",
182
182
  error:
183
- "Git Bash not found. Please install Git for Windows or set GIT_BASH_PATH environment variable.",
183
+ process.platform === "win32"
184
+ ? "Git Bash not found. Please install Git for Windows or set WAVE_GIT_BASH_PATH environment variable."
185
+ : "No suitable shell found. Please ensure bash or zsh is installed, or set WAVE_SHELL environment variable.",
184
186
  };
185
187
  }
186
188
 
@@ -242,7 +244,11 @@ The working directory persists between commands. Try to maintain your current wo
242
244
  };
243
245
  }
244
246
 
245
- const { id: taskId } = backgroundTaskManager.startShell(command);
247
+ const { id: taskId } = backgroundTaskManager.startShell(
248
+ command,
249
+ undefined,
250
+ context.workdir,
251
+ );
246
252
  const task = backgroundTaskManager.getTask(taskId);
247
253
  const outputPath = task?.outputPath;
248
254
  const backgroundMsg = [
@@ -273,7 +279,7 @@ The working directory persists between commands. Try to maintain your current wo
273
279
  );
274
280
 
275
281
  const child: ChildProcess = spawn(wrappedCommand, {
276
- shell: shellPath || true,
282
+ shell: shellPath,
277
283
  stdio: "pipe",
278
284
  detached: true,
279
285
  cwd: context.workdir,
@@ -4,11 +4,7 @@
4
4
  */
5
5
 
6
6
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
7
- import {
8
- getCurrentWorktreeSession,
9
- setCurrentWorktreeSession,
10
- type WorktreeSession,
11
- } from "../utils/worktreeSession.js";
7
+ import { type WorktreeSession } from "../utils/worktreeSession.js";
12
8
  import {
13
9
  createWorktree,
14
10
  validateWorktreeName,
@@ -72,7 +68,7 @@ export const enterWorktreeTool: ToolPlugin = {
72
68
  context: ToolContext,
73
69
  ): Promise<ToolResult> {
74
70
  // Validate not already in a worktree created by this session
75
- if (getCurrentWorktreeSession()) {
71
+ if (context.aiManager?.getWorktreeSession()) {
76
72
  return {
77
73
  success: false,
78
74
  content:
@@ -119,19 +115,13 @@ export const enterWorktreeTool: ToolPlugin = {
119
115
  originalHeadCommit: worktreeInfo.originalHeadCommit,
120
116
  };
121
117
 
122
- // Set module-level session state
123
- setCurrentWorktreeSession(session);
124
-
125
- // Update CWD via AIManager
118
+ // Set per-session worktree state and update CWD via AIManager
126
119
  const aiManager = context.aiManager;
127
120
  if (aiManager) {
121
+ aiManager.setWorktreeSession(session);
128
122
  aiManager.setWorkdir(worktreeInfo.path);
129
123
  }
130
124
 
131
- // Also update the container's Workdir entry
132
- // (Container is not directly accessible from ToolContext, but AIManager.setWorkdir
133
- // handles both its internal field and process.chdir)
134
-
135
125
  // Trigger WorktreeCreate hook if worktree is new
136
126
  let hookTriggered = false;
137
127
  if (session.isNew && context.hookManager) {
@@ -4,10 +4,6 @@
4
4
  */
5
5
 
6
6
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
7
- import {
8
- getCurrentWorktreeSession,
9
- setCurrentWorktreeSession,
10
- } from "../utils/worktreeSession.js";
11
7
  import {
12
8
  removeWorktree,
13
9
  countWorktreeChanges,
@@ -89,8 +85,8 @@ export const exitWorktreeTool: ToolPlugin = {
89
85
  };
90
86
  }
91
87
 
92
- // Validate: must be in an active worktree session
93
- const session = getCurrentWorktreeSession();
88
+ // Validate: must be in an active worktree session (for this session)
89
+ const session = context.aiManager?.getWorktreeSession();
94
90
  if (!session) {
95
91
  return {
96
92
  success: false,
@@ -139,11 +135,9 @@ export const exitWorktreeTool: ToolPlugin = {
139
135
 
140
136
  if (action === "keep") {
141
137
  // Clear session state
142
- setCurrentWorktreeSession(null);
143
-
144
- // Restore CWD
145
138
  const aiManager = context.aiManager;
146
139
  if (aiManager) {
140
+ aiManager.setWorktreeSession(null);
147
141
  aiManager.setWorkdir(originalCwd);
148
142
  }
149
143
 
@@ -170,12 +164,10 @@ export const exitWorktreeTool: ToolPlugin = {
170
164
 
171
165
  removeWorktree(worktreeInfo);
172
166
 
173
- // Clear session state
174
- setCurrentWorktreeSession(null);
175
-
176
- // Restore CWD
167
+ // Clear session state and restore CWD
177
168
  const aiManager = context.aiManager;
178
169
  if (aiManager) {
170
+ aiManager.setWorktreeSession(null);
179
171
  aiManager.setWorkdir(originalCwd);
180
172
  }
181
173
 
@@ -198,6 +198,7 @@ export interface HookJsonInput {
198
198
  compact_summary?: string; // Present for PostCompact events
199
199
  background_tasks?: BackgroundTaskInfo[]; // Present for Stop events: running background tasks snapshot
200
200
  session_crons?: SessionCronInfo[]; // Present for Stop events: session-scoped cron jobs snapshot
201
+ last_assistant_message?: string; // Present for Stop and SubagentStop events: text content of the last assistant message
201
202
  }
202
203
 
203
204
  // Describes one in-flight background task in the Stop hook input.
@@ -245,6 +246,7 @@ export interface ExtendedHookExecutionContext extends HookExecutionContext {
245
246
  compactSummary?: string; // Summary text for PostCompact
246
247
  backgroundTasks?: BackgroundTaskInfo[]; // Running background tasks snapshot (Stop only)
247
248
  sessionCrons?: SessionCronInfo[]; // Session-scoped cron jobs snapshot (Stop only)
249
+ lastAssistantMessage?: string; // Text content of last assistant message (Stop and SubagentStop only)
248
250
  }
249
251
 
250
252
  // Environment variables injected into hook processes
@@ -95,6 +95,8 @@ export interface ReasoningBlock {
95
95
  type: "reasoning";
96
96
  content: string;
97
97
  stage?: "streaming" | "end";
98
+ startTime?: number; // Unix ms, set when the first reasoning content arrives
99
+ endTime?: number; // Unix ms, set when stage transitions to "end"
98
100
  }
99
101
 
100
102
  export interface FileHistoryBlock {
@@ -1,7 +1,6 @@
1
1
  import { Container } from "./container.js";
2
2
  import { ForegroundTaskManager } from "../managers/foregroundTaskManager.js";
3
3
  import { BackgroundTaskManager } from "../managers/backgroundTaskManager.js";
4
- import { NotificationQueue } from "../managers/notificationQueue.js";
5
4
  import { MessageQueue } from "../managers/messageQueue.js";
6
5
  import { TaskManager } from "../services/taskManager.js";
7
6
  import { MessageManager } from "../managers/messageManager.js";
@@ -88,8 +87,9 @@ export function setupAgentContainer(
88
87
  container.register("MainRepoRoot", getGitMainRepoRoot(workdir));
89
88
  }
90
89
 
91
- const notificationQueue = new NotificationQueue();
92
- container.register("NotificationQueue", notificationQueue);
90
+ // Per-agent worktree session state (EnterWorktree/ExitWorktree). Stored in the
91
+ // container so it is isolated per session, not shared process-wide.
92
+ container.register("WorktreeSession", null);
93
93
 
94
94
  const messageQueue = new MessageQueue();
95
95
  container.register("MessageQueue", messageQueue);