@within-7/minto 0.4.0 → 0.4.2

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 (391) hide show
  1. package/dist/Tool.js +7 -0
  2. package/dist/Tool.js.map +2 -2
  3. package/dist/commands/agents/AgentsCommand.js +1 -1
  4. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  5. package/dist/commands/agents/constants.js +2 -2
  6. package/dist/commands/agents/constants.js.map +2 -2
  7. package/dist/commands/clear.js +4 -3
  8. package/dist/commands/clear.js.map +2 -2
  9. package/dist/commands/compact.js +2 -2
  10. package/dist/commands/compact.js.map +1 -1
  11. package/dist/commands/context.js +3 -1
  12. package/dist/commands/context.js.map +2 -2
  13. package/dist/commands/login.js +128 -0
  14. package/dist/commands/login.js.map +7 -0
  15. package/dist/commands/memory.js +33 -82
  16. package/dist/commands/memory.js.map +2 -2
  17. package/dist/commands/quit.js +3 -1
  18. package/dist/commands/quit.js.map +2 -2
  19. package/dist/commands/resume.js +39 -239
  20. package/dist/commands/resume.js.map +2 -2
  21. package/dist/commands/tasks.js +1 -1
  22. package/dist/commands/tasks.js.map +2 -2
  23. package/dist/commands/terminalSetup.js +6 -2
  24. package/dist/commands/terminalSetup.js.map +2 -2
  25. package/dist/commands.js +2 -0
  26. package/dist/commands.js.map +2 -2
  27. package/dist/components/AgentDetailView.js +126 -0
  28. package/dist/components/AgentDetailView.js.map +7 -0
  29. package/dist/components/AgentThinkingBlock.js +1 -1
  30. package/dist/components/AgentThinkingBlock.js.map +2 -2
  31. package/dist/components/AgentViewBanner.js +22 -0
  32. package/dist/components/AgentViewBanner.js.map +7 -0
  33. package/dist/components/HeaderBar.js +1 -1
  34. package/dist/components/HeaderBar.js.map +2 -2
  35. package/dist/components/Help.js +8 -1
  36. package/dist/components/Help.js.map +2 -2
  37. package/dist/components/HotkeyHelpPanel.js +26 -8
  38. package/dist/components/HotkeyHelpPanel.js.map +2 -2
  39. package/dist/components/IdleNotificationBar.js +10 -0
  40. package/dist/components/IdleNotificationBar.js.map +7 -0
  41. package/dist/components/ModelSelector/ModelSelector.js +55 -20
  42. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  43. package/dist/components/PromptInput.js +186 -115
  44. package/dist/components/PromptInput.js.map +2 -2
  45. package/dist/components/RewindPanel.js +272 -0
  46. package/dist/components/RewindPanel.js.map +7 -0
  47. package/dist/components/Spinner.js +10 -21
  48. package/dist/components/Spinner.js.map +2 -2
  49. package/dist/components/StreamingTextPreview.js +29 -0
  50. package/dist/components/StreamingTextPreview.js.map +7 -0
  51. package/dist/components/SubagentBlock.js +3 -2
  52. package/dist/components/SubagentBlock.js.map +2 -2
  53. package/dist/components/SubagentProgress.js +4 -4
  54. package/dist/components/SubagentProgress.js.map +2 -2
  55. package/dist/components/TabbedListView/SearchInput.js +1 -1
  56. package/dist/components/TabbedListView/SearchInput.js.map +2 -2
  57. package/dist/components/TabbedListView/TabbedListView.js +87 -41
  58. package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
  59. package/dist/components/TaskCard.js +4 -4
  60. package/dist/components/TaskCard.js.map +2 -2
  61. package/dist/components/TeamMemberPanel.js +107 -0
  62. package/dist/components/TeamMemberPanel.js.map +7 -0
  63. package/dist/components/ThinkingSelector.js +84 -0
  64. package/dist/components/ThinkingSelector.js.map +7 -0
  65. package/dist/components/TitledDivider.js +26 -0
  66. package/dist/components/TitledDivider.js.map +7 -0
  67. package/dist/components/TodoPanel.js +31 -30
  68. package/dist/components/TodoPanel.js.map +2 -2
  69. package/dist/components/TokenWarning.js +28 -7
  70. package/dist/components/TokenWarning.js.map +2 -2
  71. package/dist/components/messages/AssistantTextMessage.js +5 -2
  72. package/dist/components/messages/AssistantTextMessage.js.map +2 -2
  73. package/dist/components/messages/AssistantToolUseMessage.js +9 -1
  74. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  75. package/dist/components/messages/DefaultToolResultFallback.js +11 -0
  76. package/dist/components/messages/DefaultToolResultFallback.js.map +7 -0
  77. package/dist/components/messages/ParallelTasksGroupView.js +14 -6
  78. package/dist/components/messages/ParallelTasksGroupView.js.map +2 -2
  79. package/dist/components/messages/TaskInModuleView.js +27 -27
  80. package/dist/components/messages/TaskInModuleView.js.map +2 -2
  81. package/dist/components/messages/UserGuidanceMessage.js +26 -0
  82. package/dist/components/messages/UserGuidanceMessage.js.map +7 -0
  83. package/dist/components/messages/UserPromptMessage.js +2 -1
  84. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  85. package/dist/components/messages/UserTeamNotificationMessage.js +91 -0
  86. package/dist/components/messages/UserTeamNotificationMessage.js.map +7 -0
  87. package/dist/components/messages/UserTextMessage.js +8 -0
  88. package/dist/components/messages/UserTextMessage.js.map +2 -2
  89. package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js +4 -2
  90. package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js.map +2 -2
  91. package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js +18 -1
  92. package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js.map +2 -2
  93. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +12 -1
  94. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
  95. package/dist/components/permissions/PermissionRequest.js +4 -0
  96. package/dist/components/permissions/PermissionRequest.js.map +2 -2
  97. package/dist/components/permissions/PlanApprovalRequest.js +164 -0
  98. package/dist/components/permissions/PlanApprovalRequest.js.map +7 -0
  99. package/dist/constants/agentTeams.js +17 -0
  100. package/dist/constants/agentTeams.js.map +7 -0
  101. package/dist/constants/macros.js +2 -1
  102. package/dist/constants/macros.js.map +2 -2
  103. package/dist/constants/prompts/agentPrompt.js +1 -0
  104. package/dist/constants/prompts/agentPrompt.js.map +2 -2
  105. package/dist/constants/prompts/autoMemory.js +39 -0
  106. package/dist/constants/prompts/autoMemory.js.map +7 -0
  107. package/dist/constants/prompts/codeConventions.js +1 -13
  108. package/dist/constants/prompts/codeConventions.js.map +2 -2
  109. package/dist/constants/prompts/doingTasks.js +21 -2
  110. package/dist/constants/prompts/doingTasks.js.map +2 -2
  111. package/dist/constants/prompts/envInfo.js +6 -7
  112. package/dist/constants/prompts/envInfo.js.map +2 -2
  113. package/dist/constants/prompts/index.js +27 -5
  114. package/dist/constants/prompts/index.js.map +2 -2
  115. package/dist/constants/prompts/taskManagement.js +2 -43
  116. package/dist/constants/prompts/taskManagement.js.map +2 -2
  117. package/dist/constants/prompts/teamOverlays.js +50 -0
  118. package/dist/constants/prompts/teamOverlays.js.map +7 -0
  119. package/dist/constants/prompts/toneAndStyle.js +4 -29
  120. package/dist/constants/prompts/toneAndStyle.js.map +2 -2
  121. package/dist/constants/prompts/toolUsagePolicy.js +7 -22
  122. package/dist/constants/prompts/toolUsagePolicy.js.map +2 -2
  123. package/dist/constants/toolInputExamples.js +2 -2
  124. package/dist/constants/toolInputExamples.js.map +2 -2
  125. package/dist/context.js +39 -6
  126. package/dist/context.js.map +2 -2
  127. package/dist/core/backupManager.js +1 -1
  128. package/dist/core/backupManager.js.map +2 -2
  129. package/dist/core/permissions/rules/planModeRule.js +1 -1
  130. package/dist/core/permissions/rules/planModeRule.js.map +1 -1
  131. package/dist/core/permissions/rules/safeModeRule.js +1 -1
  132. package/dist/core/permissions/rules/safeModeRule.js.map +1 -1
  133. package/dist/engine/AgentEngine.js +902 -0
  134. package/dist/engine/AgentEngine.js.map +7 -0
  135. package/dist/engine/EngineRegistry.js +89 -0
  136. package/dist/engine/EngineRegistry.js.map +7 -0
  137. package/dist/engine/foregroundAdapter.js +191 -0
  138. package/dist/engine/foregroundAdapter.js.map +7 -0
  139. package/dist/engine/index.js +15 -0
  140. package/dist/engine/index.js.map +7 -0
  141. package/dist/engine/types.js +1 -0
  142. package/dist/engine/types.js.map +7 -0
  143. package/dist/entrypoints/cli.js +410 -79
  144. package/dist/entrypoints/cli.js.map +3 -3
  145. package/dist/hooks/useAgentEngine.js +129 -0
  146. package/dist/hooks/useAgentEngine.js.map +7 -0
  147. package/dist/hooks/useAgentTokenStats.js +0 -16
  148. package/dist/hooks/useAgentTokenStats.js.map +2 -2
  149. package/dist/hooks/useCanUseTool.js +47 -2
  150. package/dist/hooks/useCanUseTool.js.map +2 -2
  151. package/dist/hooks/useDeferredLoading.js +4 -1
  152. package/dist/hooks/useDeferredLoading.js.map +2 -2
  153. package/dist/hooks/useIdleNotifications.js +66 -0
  154. package/dist/hooks/useIdleNotifications.js.map +7 -0
  155. package/dist/hooks/useSessionTracking.js +9 -7
  156. package/dist/hooks/useSessionTracking.js.map +2 -2
  157. package/dist/hooks/useTeamMembers.js +51 -0
  158. package/dist/hooks/useTeamMembers.js.map +7 -0
  159. package/dist/i18n/locales/en.js +77 -12
  160. package/dist/i18n/locales/en.js.map +2 -2
  161. package/dist/i18n/locales/zh-CN.js +77 -12
  162. package/dist/i18n/locales/zh-CN.js.map +2 -2
  163. package/dist/i18n/types.js.map +1 -1
  164. package/dist/messages.js.map +2 -2
  165. package/dist/permissions.js +113 -7
  166. package/dist/permissions.js.map +2 -2
  167. package/dist/query.js +135 -37
  168. package/dist/query.js.map +2 -2
  169. package/dist/screens/REPL.js +504 -361
  170. package/dist/screens/REPL.js.map +3 -3
  171. package/dist/screens/ResumeConversation.js +199 -14
  172. package/dist/screens/ResumeConversation.js.map +2 -2
  173. package/dist/services/adapters/base.js.map +1 -1
  174. package/dist/services/agentTeams/backends/headless.js +108 -0
  175. package/dist/services/agentTeams/backends/headless.js.map +7 -0
  176. package/dist/services/agentTeams/backends/inProcess.js +102 -0
  177. package/dist/services/agentTeams/backends/inProcess.js.map +7 -0
  178. package/dist/services/agentTeams/backends/resolver.js +18 -0
  179. package/dist/services/agentTeams/backends/resolver.js.map +7 -0
  180. package/dist/services/agentTeams/backends/tmux.js +168 -0
  181. package/dist/services/agentTeams/backends/tmux.js.map +7 -0
  182. package/dist/services/agentTeams/backends/types.js +1 -0
  183. package/dist/services/agentTeams/backends/types.js.map +7 -0
  184. package/dist/services/agentTeams/heartbeat.js +88 -0
  185. package/dist/services/agentTeams/heartbeat.js.map +7 -0
  186. package/dist/services/agentTeams/index.js +42 -2
  187. package/dist/services/agentTeams/index.js.map +2 -2
  188. package/dist/services/agentTeams/injectionChannel.js +105 -0
  189. package/dist/services/agentTeams/injectionChannel.js.map +7 -0
  190. package/dist/services/agentTeams/mailbox.js +410 -30
  191. package/dist/services/agentTeams/mailbox.js.map +2 -2
  192. package/dist/services/agentTeams/messageFormatter.js +80 -0
  193. package/dist/services/agentTeams/messageFormatter.js.map +7 -0
  194. package/dist/services/agentTeams/permissionDelegation.js +71 -0
  195. package/dist/services/agentTeams/permissionDelegation.js.map +7 -0
  196. package/dist/services/agentTeams/teamEvents.js +45 -0
  197. package/dist/services/agentTeams/teamEvents.js.map +7 -0
  198. package/dist/services/agentTeams/teamManager.js +251 -34
  199. package/dist/services/agentTeams/teamManager.js.map +2 -2
  200. package/dist/services/agentTeams/teamTaskStore.js +290 -61
  201. package/dist/services/agentTeams/teamTaskStore.js.map +2 -2
  202. package/dist/services/agentTeams/teammateSpawner.js +99 -18
  203. package/dist/services/agentTeams/teammateSpawner.js.map +2 -2
  204. package/dist/services/hookExecutor.js +51 -8
  205. package/dist/services/hookExecutor.js.map +2 -2
  206. package/dist/services/llm/anthropicProvider.js +56 -59
  207. package/dist/services/llm/anthropicProvider.js.map +2 -2
  208. package/dist/services/llm/dispatch.js +24 -5
  209. package/dist/services/llm/dispatch.js.map +2 -2
  210. package/dist/services/llm/openaiProvider.js +115 -136
  211. package/dist/services/llm/openaiProvider.js.map +3 -3
  212. package/dist/services/llm/types.js +89 -15
  213. package/dist/services/llm/types.js.map +2 -2
  214. package/dist/services/mcpClient.js +80 -4
  215. package/dist/services/mcpClient.js.map +2 -2
  216. package/dist/services/mintoAuth.js +299 -0
  217. package/dist/services/mintoAuth.js.map +7 -0
  218. package/dist/services/oauth.js +3 -3
  219. package/dist/services/oauth.js.map +2 -2
  220. package/dist/services/openai.js +91 -20
  221. package/dist/services/openai.js.map +2 -2
  222. package/dist/services/plugins/pluginRuntime.js +11 -5
  223. package/dist/services/plugins/pluginRuntime.js.map +2 -2
  224. package/dist/services/plugins/pluginValidation.js +4 -2
  225. package/dist/services/plugins/pluginValidation.js.map +2 -2
  226. package/dist/services/sandbox/sandboxController.js +11 -3
  227. package/dist/services/sandbox/sandboxController.js.map +2 -2
  228. package/dist/services/sessionMemoryInjector.js +77 -0
  229. package/dist/services/sessionMemoryInjector.js.map +7 -0
  230. package/dist/services/systemReminder.js +130 -8
  231. package/dist/services/systemReminder.js.map +2 -2
  232. package/dist/services/taskStore.js +199 -8
  233. package/dist/services/taskStore.js.map +3 -3
  234. package/dist/services/topicDetector.js +169 -0
  235. package/dist/services/topicDetector.js.map +7 -0
  236. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +0 -13
  237. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  238. package/dist/tools/BashTool/BashTool.js +51 -28
  239. package/dist/tools/BashTool/BashTool.js.map +2 -2
  240. package/dist/tools/BashTool/prompt.js +95 -118
  241. package/dist/tools/BashTool/prompt.js.map +2 -2
  242. package/dist/tools/BashTool/utils.js +39 -1
  243. package/dist/tools/BashTool/utils.js.map +2 -2
  244. package/dist/tools/EnterWorktreeTool/EnterWorktreeTool.js +121 -0
  245. package/dist/tools/EnterWorktreeTool/EnterWorktreeTool.js.map +7 -0
  246. package/dist/tools/EnterWorktreeTool/prompt.js +22 -0
  247. package/dist/tools/EnterWorktreeTool/prompt.js.map +7 -0
  248. package/dist/tools/FileEditTool/FileEditTool.js +9 -4
  249. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  250. package/dist/tools/FileEditTool/prompt.js +3 -7
  251. package/dist/tools/FileEditTool/prompt.js.map +2 -2
  252. package/dist/tools/FileReadTool/FileReadTool.js +125 -3
  253. package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
  254. package/dist/tools/FileReadTool/prompt.js +1 -2
  255. package/dist/tools/FileReadTool/prompt.js.map +2 -2
  256. package/dist/tools/FileWriteTool/prompt.js +3 -5
  257. package/dist/tools/FileWriteTool/prompt.js.map +2 -2
  258. package/dist/tools/GlobTool/GlobTool.js +3 -2
  259. package/dist/tools/GlobTool/GlobTool.js.map +2 -2
  260. package/dist/tools/GrepTool/GrepTool.js +16 -5
  261. package/dist/tools/GrepTool/GrepTool.js.map +2 -2
  262. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
  263. package/dist/tools/MCPSearchTool/MCPSearchTool.js +172 -0
  264. package/dist/tools/MCPSearchTool/MCPSearchTool.js.map +7 -0
  265. package/dist/tools/MCPSearchTool/prompt.js +77 -0
  266. package/dist/tools/MCPSearchTool/prompt.js.map +7 -0
  267. package/dist/tools/MultiEditTool/prompt.js +4 -7
  268. package/dist/tools/MultiEditTool/prompt.js.map +2 -2
  269. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +12 -8
  270. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
  271. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +54 -1
  272. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
  273. package/dist/tools/PlanModeTool/prompt.js +23 -74
  274. package/dist/tools/PlanModeTool/prompt.js.map +2 -2
  275. package/dist/tools/SendMessageTool/SendMessageTool.js +341 -0
  276. package/dist/tools/SendMessageTool/SendMessageTool.js.map +7 -0
  277. package/dist/tools/SendMessageTool/prompt.js +44 -0
  278. package/dist/tools/SendMessageTool/prompt.js.map +7 -0
  279. package/dist/tools/TaskCreateTool/prompt.js +15 -4
  280. package/dist/tools/TaskCreateTool/prompt.js.map +2 -2
  281. package/dist/tools/TaskListTool/prompt.js +18 -3
  282. package/dist/tools/TaskListTool/prompt.js.map +2 -2
  283. package/dist/tools/TaskOutputTool/prompt.js +4 -3
  284. package/dist/tools/TaskOutputTool/prompt.js.map +2 -2
  285. package/dist/tools/TaskTool/TaskTool.js +762 -98
  286. package/dist/tools/TaskTool/TaskTool.js.map +3 -3
  287. package/dist/tools/TaskTool/constants.js +8 -2
  288. package/dist/tools/TaskTool/constants.js.map +2 -2
  289. package/dist/tools/TaskTool/prompt.js +74 -70
  290. package/dist/tools/TaskTool/prompt.js.map +2 -2
  291. package/dist/tools/TaskUpdateTool/TaskUpdateTool.js +15 -1
  292. package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +2 -2
  293. package/dist/tools/TeamCreateTool/TeamCreateTool.js +129 -0
  294. package/dist/tools/TeamCreateTool/TeamCreateTool.js.map +7 -0
  295. package/dist/tools/TeamCreateTool/prompt.js +58 -0
  296. package/dist/tools/TeamCreateTool/prompt.js.map +7 -0
  297. package/dist/tools/TeamDeleteTool/TeamDeleteTool.js +151 -0
  298. package/dist/tools/TeamDeleteTool/TeamDeleteTool.js.map +7 -0
  299. package/dist/tools/TeamDeleteTool/prompt.js +16 -0
  300. package/dist/tools/TeamDeleteTool/prompt.js.map +7 -0
  301. package/dist/tools/URLFetcherTool/URLFetcherTool.js +106 -15
  302. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
  303. package/dist/tools/URLFetcherTool/prompt.js +3 -2
  304. package/dist/tools/URLFetcherTool/prompt.js.map +2 -2
  305. package/dist/tools/WebSearchTool/WebSearchTool.js +2 -1
  306. package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
  307. package/dist/tools/WebSearchTool/prompt.js +5 -4
  308. package/dist/tools/WebSearchTool/prompt.js.map +2 -2
  309. package/dist/tools.js +100 -20
  310. package/dist/tools.js.map +2 -2
  311. package/dist/types/PermissionMode.js +35 -6
  312. package/dist/types/PermissionMode.js.map +2 -2
  313. package/dist/types/hooks.js +2 -0
  314. package/dist/types/hooks.js.map +2 -2
  315. package/dist/types/plugin.js +2 -0
  316. package/dist/types/plugin.js.map +3 -3
  317. package/dist/utils/CircuitBreaker.js +15 -9
  318. package/dist/utils/CircuitBreaker.js.map +2 -2
  319. package/dist/utils/agentLoader.js +249 -112
  320. package/dist/utils/agentLoader.js.map +2 -2
  321. package/dist/utils/animationManager.js +40 -3
  322. package/dist/utils/animationManager.js.map +2 -2
  323. package/dist/utils/ask.js +7 -6
  324. package/dist/utils/ask.js.map +2 -2
  325. package/dist/utils/atomicWrite.js +23 -0
  326. package/dist/utils/atomicWrite.js.map +7 -0
  327. package/dist/utils/autoCompactCore.js +73 -56
  328. package/dist/utils/autoCompactCore.js.map +2 -2
  329. package/dist/utils/autoMemoryPaths.js +89 -0
  330. package/dist/utils/autoMemoryPaths.js.map +7 -0
  331. package/dist/utils/config.js +63 -38
  332. package/dist/utils/config.js.map +2 -2
  333. package/dist/utils/configSchema.js +13 -8
  334. package/dist/utils/configSchema.js.map +2 -2
  335. package/dist/utils/credentials/index.js +14 -0
  336. package/dist/utils/credentials/index.js.map +2 -2
  337. package/dist/utils/dualPath.js +24 -0
  338. package/dist/utils/dualPath.js.map +7 -0
  339. package/dist/utils/exit.js +66 -7
  340. package/dist/utils/exit.js.map +2 -2
  341. package/dist/utils/externalEditor.js +155 -0
  342. package/dist/utils/externalEditor.js.map +7 -0
  343. package/dist/utils/fileLock.js +67 -0
  344. package/dist/utils/fileLock.js.map +7 -0
  345. package/dist/utils/format.js +24 -14
  346. package/dist/utils/format.js.map +2 -2
  347. package/dist/utils/globalErrorHandler.js +5 -96
  348. package/dist/utils/globalErrorHandler.js.map +3 -3
  349. package/dist/utils/groupHandlers/parallelTasksHandler.js +5 -3
  350. package/dist/utils/groupHandlers/parallelTasksHandler.js.map +2 -2
  351. package/dist/utils/groupHandlers/taskHandler.js +2 -2
  352. package/dist/utils/groupHandlers/taskHandler.js.map +2 -2
  353. package/dist/utils/hookManager.js +64 -6
  354. package/dist/utils/hookManager.js.map +2 -2
  355. package/dist/utils/log.js +6 -2
  356. package/dist/utils/log.js.map +2 -2
  357. package/dist/utils/markdown.js +237 -19
  358. package/dist/utils/markdown.js.map +2 -2
  359. package/dist/utils/messageContextManager.js +18 -5
  360. package/dist/utils/messageContextManager.js.map +2 -2
  361. package/dist/utils/messageGroupManager.js +1 -1
  362. package/dist/utils/messageGroupManager.js.map +2 -2
  363. package/dist/utils/messages.js +104 -46
  364. package/dist/utils/messages.js.map +2 -2
  365. package/dist/utils/model.js +2 -2
  366. package/dist/utils/model.js.map +2 -2
  367. package/dist/utils/pasteCache.js +8 -4
  368. package/dist/utils/pasteCache.js.map +2 -2
  369. package/dist/utils/pluginLoader.js +18 -0
  370. package/dist/utils/pluginLoader.js.map +2 -2
  371. package/dist/utils/secureKeyStorage.js +36 -7
  372. package/dist/utils/secureKeyStorage.js.map +2 -2
  373. package/dist/utils/simpleMode.js +7 -0
  374. package/dist/utils/simpleMode.js.map +7 -0
  375. package/dist/utils/streamingState.js +11 -1
  376. package/dist/utils/streamingState.js.map +2 -2
  377. package/dist/utils/taskDisplayUtils.js +2 -1
  378. package/dist/utils/taskDisplayUtils.js.map +2 -2
  379. package/dist/utils/teamConfig.js +2 -2
  380. package/dist/utils/teamConfig.js.map +2 -2
  381. package/dist/utils/thinking.js +6 -2
  382. package/dist/utils/thinking.js.map +3 -3
  383. package/dist/utils/tokenProgress.js +55 -0
  384. package/dist/utils/tokenProgress.js.map +7 -0
  385. package/dist/utils/toolRiskClassification.js +26 -17
  386. package/dist/utils/toolRiskClassification.js.map +2 -2
  387. package/dist/utils/tooling/toolError.js +12 -0
  388. package/dist/utils/tooling/toolError.js.map +7 -0
  389. package/dist/version.js +2 -2
  390. package/dist/version.js.map +1 -1
  391. package/package.json +10 -8
@@ -0,0 +1,168 @@
1
+ import { debug as debugLogger } from "../../../utils/debugLogger.js";
2
+ import { filterSensitiveEnv } from "../../mcpClient.js";
3
+ import { safeQuote } from "../index.js";
4
+ const FORCE_KILL_TIMEOUT = 5e3;
5
+ class TmuxBackend {
6
+ mode = "tmux";
7
+ paneIds = /* @__PURE__ */ new Map();
8
+ exitCallbacks = /* @__PURE__ */ new Map();
9
+ killTimers = /* @__PURE__ */ new Map();
10
+ exitPollers = /* @__PURE__ */ new Map();
11
+ async spawn(options) {
12
+ const { execFileSync } = await import("child_process");
13
+ const cmdParts = [
14
+ "minto",
15
+ "--headless-agent",
16
+ "--team",
17
+ options.teamName,
18
+ "--agent-id",
19
+ options.agentId,
20
+ "--agent-name",
21
+ options.agentName,
22
+ "--agent-type",
23
+ options.agentType
24
+ ];
25
+ if (options.maxTurns) cmdParts.push("--max-turns", String(options.maxTurns));
26
+ if (options.model) cmdParts.push("--model", options.model);
27
+ if (options.mode) cmdParts.push("--permission-mode", options.mode);
28
+ if (options.planModeRequired) cmdParts.push("--plan-mode-required");
29
+ if (options.color) cmdParts.push("--agent-color", options.color);
30
+ if (options.parentSessionId)
31
+ cmdParts.push("--parent-session-id", options.parentSessionId);
32
+ cmdParts.push("--", options.prompt);
33
+ const safeCmd = cmdParts.map(safeQuote).join(" ");
34
+ const envSetup = [
35
+ `MINTO_TEAM_NAME=${safeQuote(options.teamName)}`,
36
+ `CLAUDE_CODE_TEAM_NAME=${safeQuote(options.teamName)}`,
37
+ `MINTO_AGENT_ID=${safeQuote(options.agentId)}`,
38
+ `CLAUDE_CODE_AGENT_ID=${safeQuote(options.agentId)}`,
39
+ `MINTO_AGENT_TYPE=${safeQuote(options.agentType)}`,
40
+ `CLAUDE_CODE_AGENT_TYPE=${safeQuote(options.agentType)}`,
41
+ `MINTO_AGENT_NAME=${safeQuote(options.agentName)}`,
42
+ `CLAUDE_CODE_AGENT_NAME=${safeQuote(options.agentName)}`
43
+ ].map((e) => `export ${e}`).join("; ");
44
+ const fullCmd = `${envSetup}; ${safeCmd}`;
45
+ try {
46
+ const filteredEnv = filterSensitiveEnv(process.env);
47
+ const spawnResult = execFileSync(
48
+ "tmux",
49
+ ["split-window", "-h", "-P", "-F", "#{pane_id}", fullCmd],
50
+ {
51
+ stdio: "pipe",
52
+ encoding: "utf-8",
53
+ cwd: options.cwd,
54
+ env: filteredEnv
55
+ }
56
+ );
57
+ const paneId = spawnResult.trim() || void 0;
58
+ const handle = {
59
+ id: options.agentId,
60
+ mode: "tmux"
61
+ };
62
+ if (paneId) {
63
+ this.paneIds.set(options.agentId, paneId);
64
+ }
65
+ return handle;
66
+ } catch (error) {
67
+ debugLogger.error("TMUX_BACKEND_SPAWN", {
68
+ agentId: options.agentId,
69
+ error: error instanceof Error ? error.message : String(error)
70
+ });
71
+ throw error;
72
+ }
73
+ }
74
+ signal(handle, signal) {
75
+ const paneId = this.paneIds.get(handle.id);
76
+ if (!paneId) return;
77
+ try {
78
+ const { execFileSync } = require("child_process");
79
+ if (signal === "abort" || signal === "shutdown") {
80
+ execFileSync("tmux", ["send-keys", "-t", paneId, "C-c", ""], {
81
+ stdio: "pipe"
82
+ });
83
+ }
84
+ } catch {
85
+ }
86
+ }
87
+ isAlive(handle) {
88
+ const paneId = this.paneIds.get(handle.id);
89
+ if (!paneId) return false;
90
+ try {
91
+ const { execFileSync } = require("child_process");
92
+ execFileSync("tmux", ["display-message", "-t", paneId, "-p", ""], {
93
+ stdio: "pipe"
94
+ });
95
+ return true;
96
+ } catch {
97
+ return false;
98
+ }
99
+ }
100
+ async kill(handle) {
101
+ const paneId = this.paneIds.get(handle.id);
102
+ if (!paneId) return;
103
+ try {
104
+ const { execFileSync } = require("child_process");
105
+ execFileSync("tmux", ["send-keys", "-t", paneId, "C-c", ""], {
106
+ stdio: "pipe"
107
+ });
108
+ const timer = setTimeout(() => {
109
+ this.killTimers.delete(handle.id);
110
+ try {
111
+ execFileSync("tmux", ["kill-pane", "-t", paneId], { stdio: "pipe" });
112
+ } catch {
113
+ }
114
+ this.cleanup(handle.id);
115
+ }, FORCE_KILL_TIMEOUT);
116
+ timer.unref();
117
+ this.killTimers.set(handle.id, timer);
118
+ } catch {
119
+ try {
120
+ const { execFileSync } = require("child_process");
121
+ execFileSync("tmux", ["kill-pane", "-t", paneId], { stdio: "pipe" });
122
+ } catch {
123
+ }
124
+ this.cleanup(handle.id);
125
+ }
126
+ }
127
+ onExit(handle, callback) {
128
+ const existing = this.exitCallbacks.get(handle.id) ?? [];
129
+ existing.push(callback);
130
+ this.exitCallbacks.set(handle.id, existing);
131
+ if (!this.exitPollers.has(handle.id) && this.paneIds.has(handle.id)) {
132
+ const poller = setInterval(() => {
133
+ if (!this.isAlive(handle)) {
134
+ clearInterval(poller);
135
+ this.exitPollers.delete(handle.id);
136
+ this.cleanup(handle.id);
137
+ }
138
+ }, 5e3);
139
+ poller.unref();
140
+ this.exitPollers.set(handle.id, poller);
141
+ }
142
+ }
143
+ cleanup(agentId) {
144
+ this.paneIds.delete(agentId);
145
+ const killTimer = this.killTimers.get(agentId);
146
+ if (killTimer) {
147
+ clearTimeout(killTimer);
148
+ this.killTimers.delete(agentId);
149
+ }
150
+ const poller = this.exitPollers.get(agentId);
151
+ if (poller) {
152
+ clearInterval(poller);
153
+ this.exitPollers.delete(agentId);
154
+ }
155
+ const cbs = this.exitCallbacks.get(agentId) ?? [];
156
+ for (const cb of cbs) {
157
+ try {
158
+ cb(0);
159
+ } catch {
160
+ }
161
+ }
162
+ this.exitCallbacks.delete(agentId);
163
+ }
164
+ }
165
+ export {
166
+ TmuxBackend
167
+ };
168
+ //# sourceMappingURL=tmux.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/services/agentTeams/backends/tmux.ts"],
4
+ "sourcesContent": ["/**\n * TmuxBackend\n *\n * Spawns teammate agents in separate tmux panes (or iTerm2 panes).\n * Each agent gets its own terminal panel, enabling visual monitoring\n * of agent activity in real-time.\n *\n * Auto-detected when running inside a tmux session or iTerm2.\n */\n\nimport type { DisplayBackend, AgentHandle, SpawnOptions } from './types'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { filterSensitiveEnv } from '@services/mcpClient'\nimport { safeQuote } from '../index'\n\n/** Grace period before SIGKILL after SIGTERM (ms) */\nconst FORCE_KILL_TIMEOUT = 5000\n\nexport class TmuxBackend implements DisplayBackend {\n readonly mode = 'tmux'\n private paneIds = new Map<string, string>()\n private exitCallbacks = new Map<string, ((code: number | null) => void)[]>()\n private killTimers = new Map<string, ReturnType<typeof setTimeout>>()\n private exitPollers = new Map<string, ReturnType<typeof setInterval>>()\n\n async spawn(options: SpawnOptions): Promise<AgentHandle> {\n const { execFileSync } = await import('child_process')\n\n // Build the command that tmux will execute in the new pane.\n const cmdParts = [\n 'minto',\n '--headless-agent',\n '--team',\n options.teamName,\n '--agent-id',\n options.agentId,\n '--agent-name',\n options.agentName,\n '--agent-type',\n options.agentType,\n ]\n\n if (options.maxTurns) cmdParts.push('--max-turns', String(options.maxTurns))\n if (options.model) cmdParts.push('--model', options.model)\n if (options.mode) cmdParts.push('--permission-mode', options.mode)\n if (options.planModeRequired) cmdParts.push('--plan-mode-required')\n if (options.color) cmdParts.push('--agent-color', options.color)\n if (options.parentSessionId)\n cmdParts.push('--parent-session-id', options.parentSessionId)\n cmdParts.push('--', options.prompt)\n\n const safeCmd = cmdParts.map(safeQuote).join(' ')\n\n // Set environment variables for the pane (MINTO_* + CLAUDE_CODE_* compat)\n const envSetup = [\n `MINTO_TEAM_NAME=${safeQuote(options.teamName)}`,\n `CLAUDE_CODE_TEAM_NAME=${safeQuote(options.teamName)}`,\n `MINTO_AGENT_ID=${safeQuote(options.agentId)}`,\n `CLAUDE_CODE_AGENT_ID=${safeQuote(options.agentId)}`,\n `MINTO_AGENT_TYPE=${safeQuote(options.agentType)}`,\n `CLAUDE_CODE_AGENT_TYPE=${safeQuote(options.agentType)}`,\n `MINTO_AGENT_NAME=${safeQuote(options.agentName)}`,\n `CLAUDE_CODE_AGENT_NAME=${safeQuote(options.agentName)}`,\n ]\n .map(e => `export ${e}`)\n .join('; ')\n\n const fullCmd = `${envSetup}; ${safeCmd}`\n\n try {\n // All paths (iTerm2 + tmux, pure iTerm2, standard tmux) use the same\n // tmux split-window command. Merged to eliminate redundant branches.\n // Use -P -F to directly get the new pane's ID from split-window\n // Filter sensitive environment variables to prevent credential leaking to child panes\n const filteredEnv = filterSensitiveEnv(process.env)\n const spawnResult = execFileSync(\n 'tmux',\n ['split-window', '-h', '-P', '-F', '#{pane_id}', fullCmd],\n {\n stdio: 'pipe',\n encoding: 'utf-8',\n cwd: options.cwd,\n env: filteredEnv,\n },\n )\n const paneId = spawnResult.trim() || undefined\n\n const handle: AgentHandle = {\n id: options.agentId,\n mode: 'tmux',\n }\n\n if (paneId) {\n this.paneIds.set(options.agentId, paneId)\n }\n\n return handle\n } catch (error) {\n debugLogger.error('TMUX_BACKEND_SPAWN', {\n agentId: options.agentId,\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n }\n\n signal(handle: AgentHandle, signal: 'abort' | 'shutdown'): void {\n const paneId = this.paneIds.get(handle.id)\n if (!paneId) return\n\n try {\n const { execFileSync } = require('child_process')\n if (signal === 'abort' || signal === 'shutdown') {\n // Send Ctrl+C to the pane\n execFileSync('tmux', ['send-keys', '-t', paneId, 'C-c', ''], {\n stdio: 'pipe',\n })\n }\n } catch {\n // Pane may have already exited\n }\n }\n\n isAlive(handle: AgentHandle): boolean {\n const paneId = this.paneIds.get(handle.id)\n if (!paneId) return false\n\n try {\n const { execFileSync } = require('child_process')\n // Use display-message targeting the specific pane to verify it exists\n // has-session checks sessions not panes, which gives false positives\n execFileSync('tmux', ['display-message', '-t', paneId, '-p', ''], {\n stdio: 'pipe',\n })\n return true\n } catch {\n return false\n }\n }\n\n async kill(handle: AgentHandle): Promise<void> {\n const paneId = this.paneIds.get(handle.id)\n if (!paneId) return\n\n try {\n const { execFileSync } = require('child_process')\n // First try graceful Ctrl+C\n execFileSync('tmux', ['send-keys', '-t', paneId, 'C-c', ''], {\n stdio: 'pipe',\n })\n\n // Wait for grace period, then kill the pane\n const timer = setTimeout(() => {\n this.killTimers.delete(handle.id)\n try {\n execFileSync('tmux', ['kill-pane', '-t', paneId], { stdio: 'pipe' })\n } catch {\n // Pane may have already exited\n }\n this.cleanup(handle.id)\n }, FORCE_KILL_TIMEOUT)\n timer.unref()\n this.killTimers.set(handle.id, timer)\n } catch {\n // If Ctrl+C fails, force kill the pane\n try {\n const { execFileSync } = require('child_process')\n execFileSync('tmux', ['kill-pane', '-t', paneId], { stdio: 'pipe' })\n } catch {\n // Pane already gone\n }\n this.cleanup(handle.id)\n }\n }\n\n onExit(handle: AgentHandle, callback: (code: number | null) => void): void {\n const existing = this.exitCallbacks.get(handle.id) ?? []\n existing.push(callback)\n this.exitCallbacks.set(handle.id, existing)\n\n // Start periodic pane alive polling if not already running\n if (!this.exitPollers.has(handle.id) && this.paneIds.has(handle.id)) {\n const poller = setInterval(() => {\n if (!this.isAlive(handle)) {\n clearInterval(poller)\n this.exitPollers.delete(handle.id)\n this.cleanup(handle.id)\n }\n }, 5000)\n poller.unref()\n this.exitPollers.set(handle.id, poller)\n }\n }\n\n private cleanup(agentId: string): void {\n this.paneIds.delete(agentId)\n const killTimer = this.killTimers.get(agentId)\n if (killTimer) {\n clearTimeout(killTimer)\n this.killTimers.delete(agentId)\n }\n const poller = this.exitPollers.get(agentId)\n if (poller) {\n clearInterval(poller)\n this.exitPollers.delete(agentId)\n }\n const cbs = this.exitCallbacks.get(agentId) ?? []\n for (const cb of cbs) {\n try {\n cb(0)\n } catch {\n // Don't let callback errors break cleanup\n }\n }\n this.exitCallbacks.delete(agentId)\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,88 @@
1
+ import {
2
+ formatTeamMessage,
3
+ formatIdleNotificationForInjection,
4
+ parseIdleNotification,
5
+ humanizeProtocolMessage
6
+ } from "./messageFormatter.js";
7
+ import { debug as debugLogger } from "../../utils/debugLogger.js";
8
+ class AgentHeartbeat {
9
+ timer = null;
10
+ agentId = "";
11
+ teamName = "";
12
+ channel = null;
13
+ /**
14
+ * Start the heartbeat for a given agent/team.
15
+ * Polls the mailbox at the specified interval and pushes
16
+ * formatted messages to the injection channel.
17
+ */
18
+ start(agentId, teamName, channel, options = {}) {
19
+ if (this.timer) return;
20
+ this.agentId = agentId;
21
+ this.teamName = teamName;
22
+ this.channel = channel;
23
+ const interval = options.interval ?? 2e3;
24
+ this.timer = setInterval(() => {
25
+ this.poll();
26
+ }, interval);
27
+ this.poll();
28
+ }
29
+ /**
30
+ * Stop the heartbeat timer.
31
+ */
32
+ stop() {
33
+ if (this.timer) {
34
+ clearInterval(this.timer);
35
+ this.timer = null;
36
+ }
37
+ this.channel = null;
38
+ }
39
+ /**
40
+ * Whether the heartbeat is currently running.
41
+ */
42
+ get running() {
43
+ return this.timer !== null;
44
+ }
45
+ /**
46
+ * Single poll cycle: check mailbox, format messages, push to channel.
47
+ */
48
+ poll() {
49
+ if (!this.channel || !this.teamName) return;
50
+ try {
51
+ const { getTeam } = require("./teamManager");
52
+ const entry = getTeam(this.teamName);
53
+ if (!entry) {
54
+ this.stop();
55
+ return;
56
+ }
57
+ const unread = entry.mailbox.getUnread(this.agentId);
58
+ if (unread.length === 0) return;
59
+ const regularMessages = [];
60
+ for (const msg of unread) {
61
+ const idleNotification = parseIdleNotification(msg.text);
62
+ if (idleNotification) {
63
+ const formatted = formatIdleNotificationForInjection(idleNotification);
64
+ this.channel.push(formatted, "task", void 0, msg.id);
65
+ } else {
66
+ const friendlySummary = humanizeProtocolMessage(msg.text);
67
+ if (friendlySummary) {
68
+ regularMessages.push({ ...msg, summary: friendlySummary });
69
+ } else {
70
+ regularMessages.push(msg);
71
+ }
72
+ }
73
+ }
74
+ if (regularMessages.length > 0) {
75
+ const formatted = regularMessages.map((m) => formatTeamMessage(m)).join("\n\n");
76
+ const compositeId = regularMessages.map((m) => m.id).sort().join("+");
77
+ this.channel.push(formatted, "team", void 0, compositeId);
78
+ }
79
+ entry.mailbox.markRead(unread.map((m) => m.id));
80
+ } catch (e) {
81
+ debugLogger.warn("HEARTBEAT_POLL_ERROR", { error: e });
82
+ }
83
+ }
84
+ }
85
+ export {
86
+ AgentHeartbeat
87
+ };
88
+ //# sourceMappingURL=heartbeat.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/services/agentTeams/heartbeat.ts"],
4
+ "sourcesContent": ["/**\n * Agent Heartbeat\n *\n * Periodic timer that checks the team mailbox for unread messages\n * addressed to the team-lead (main REPL agent) and pushes them\n * into the injection channel for between-turns delivery.\n *\n * This is the core mechanism that enables team-lead to receive\n * teammate messages without explicit polling in the REPL loop.\n */\n\nimport type { MessageInjectionChannel } from './injectionChannel'\nimport {\n formatTeamMessage,\n formatIdleNotificationForInjection,\n parseIdleNotification,\n humanizeProtocolMessage,\n} from './messageFormatter'\nimport type { TeamMessage } from '../../types/agentTeams'\nimport { debug as debugLogger } from '../../utils/debugLogger'\n\nexport interface HeartbeatOptions {\n /** Polling interval in ms. Default: 2000 */\n interval?: number\n}\n\nexport class AgentHeartbeat {\n private timer: ReturnType<typeof setInterval> | null = null\n private agentId: string = ''\n private teamName: string = ''\n private channel: MessageInjectionChannel | null = null\n\n /**\n * Start the heartbeat for a given agent/team.\n * Polls the mailbox at the specified interval and pushes\n * formatted messages to the injection channel.\n */\n start(\n agentId: string,\n teamName: string,\n channel: MessageInjectionChannel,\n options: HeartbeatOptions = {},\n ): void {\n // Don't double-start\n if (this.timer) return\n\n this.agentId = agentId\n this.teamName = teamName\n this.channel = channel\n\n const interval = options.interval ?? 2000\n\n this.timer = setInterval(() => {\n this.poll()\n }, interval)\n\n // Run initial poll immediately\n this.poll()\n }\n\n /**\n * Stop the heartbeat timer.\n */\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer)\n this.timer = null\n }\n this.channel = null\n }\n\n /**\n * Whether the heartbeat is currently running.\n */\n get running(): boolean {\n return this.timer !== null\n }\n\n /**\n * Single poll cycle: check mailbox, format messages, push to channel.\n */\n private poll(): void {\n if (!this.channel || !this.teamName) return\n\n try {\n // Lazy import to avoid circular dependency\n const { getTeam } = require('./teamManager')\n const entry = getTeam(this.teamName)\n if (!entry) {\n // Team disbanded \u2014 auto-stop heartbeat\n this.stop()\n return\n }\n\n const unread = entry.mailbox.getUnread(this.agentId)\n if (unread.length === 0) return\n\n // Process each message \u2014 detect idle notifications vs regular messages\n const regularMessages: TeamMessage[] = []\n\n for (const msg of unread) {\n const idleNotification = parseIdleNotification(msg.text)\n if (idleNotification) {\n // Format as structured task notification\n const formatted = formatIdleNotificationForInjection(idleNotification)\n this.channel.push(formatted, 'task', undefined, msg.id)\n } else {\n // Humanize protocol messages for display\n const friendlySummary = humanizeProtocolMessage(msg.text)\n if (friendlySummary) {\n regularMessages.push({ ...msg, summary: friendlySummary })\n } else {\n regularMessages.push(msg)\n }\n }\n }\n\n // Format regular team messages and push as a batch\n if (regularMessages.length > 0) {\n const formatted = regularMessages\n .map(m => formatTeamMessage(m))\n .join('\\n\\n')\n const compositeId = regularMessages\n .map(m => m.id)\n .sort()\n .join('+')\n this.channel.push(formatted, 'team', undefined, compositeId)\n }\n\n // Mark all as read\n entry.mailbox.markRead(unread.map((m: TeamMessage) => m.id))\n } catch (e) {\n // Non-fatal: polling failures don't break the heartbeat\n debugLogger.warn('HEARTBEAT_POLL_ERROR', { error: e })\n }\n }\n}\n"],
5
+ "mappings": "AAYA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,SAAS,mBAAmB;AAO9B,MAAM,eAAe;AAAA,EAClB,QAA+C;AAAA,EAC/C,UAAkB;AAAA,EAClB,WAAmB;AAAA,EACnB,UAA0C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOlD,MACE,SACA,UACA,SACA,UAA4B,CAAC,GACvB;AAEN,QAAI,KAAK,MAAO;AAEhB,SAAK,UAAU;AACf,SAAK,WAAW;AAChB,SAAK,UAAU;AAEf,UAAM,WAAW,QAAQ,YAAY;AAErC,SAAK,QAAQ,YAAY,MAAM;AAC7B,WAAK,KAAK;AAAA,IACZ,GAAG,QAAQ;AAGX,SAAK,KAAK;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,OAAa;AACX,QAAI,KAAK,OAAO;AACd,oBAAc,KAAK,KAAK;AACxB,WAAK,QAAQ;AAAA,IACf;AACA,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAmB;AACrB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKQ,OAAa;AACnB,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,SAAU;AAErC,QAAI;AAEF,YAAM,EAAE,QAAQ,IAAI,QAAQ,eAAe;AAC3C,YAAM,QAAQ,QAAQ,KAAK,QAAQ;AACnC,UAAI,CAAC,OAAO;AAEV,aAAK,KAAK;AACV;AAAA,MACF;AAEA,YAAM,SAAS,MAAM,QAAQ,UAAU,KAAK,OAAO;AACnD,UAAI,OAAO,WAAW,EAAG;AAGzB,YAAM,kBAAiC,CAAC;AAExC,iBAAW,OAAO,QAAQ;AACxB,cAAM,mBAAmB,sBAAsB,IAAI,IAAI;AACvD,YAAI,kBAAkB;AAEpB,gBAAM,YAAY,mCAAmC,gBAAgB;AACrE,eAAK,QAAQ,KAAK,WAAW,QAAQ,QAAW,IAAI,EAAE;AAAA,QACxD,OAAO;AAEL,gBAAM,kBAAkB,wBAAwB,IAAI,IAAI;AACxD,cAAI,iBAAiB;AACnB,4BAAgB,KAAK,EAAE,GAAG,KAAK,SAAS,gBAAgB,CAAC;AAAA,UAC3D,OAAO;AACL,4BAAgB,KAAK,GAAG;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAGA,UAAI,gBAAgB,SAAS,GAAG;AAC9B,cAAM,YAAY,gBACf,IAAI,OAAK,kBAAkB,CAAC,CAAC,EAC7B,KAAK,MAAM;AACd,cAAM,cAAc,gBACjB,IAAI,OAAK,EAAE,EAAE,EACb,KAAK,EACL,KAAK,GAAG;AACX,aAAK,QAAQ,KAAK,WAAW,QAAQ,QAAW,WAAW;AAAA,MAC7D;AAGA,YAAM,QAAQ,SAAS,OAAO,IAAI,CAAC,MAAmB,EAAE,EAAE,CAAC;AAAA,IAC7D,SAAS,GAAG;AAEV,kBAAY,KAAK,wBAAwB,EAAE,OAAO,EAAE,CAAC;AAAA,IACvD;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -1,35 +1,75 @@
1
1
  import {
2
2
  isAgentTeamsEnabled,
3
+ sanitizeTeamName,
3
4
  createTeam,
4
5
  addTeammate,
5
6
  updateTeammateStatus,
6
7
  getTeam,
7
8
  getActiveTeams,
8
9
  disbandTeam,
10
+ disbandAllTeams,
9
11
  loadTeam,
10
- resolveDisplayMode
12
+ resolveDisplayMode,
13
+ registerAgentAbortController,
14
+ unregisterAgentAbortController,
15
+ updateTeammateWorktree
11
16
  } from "./teamManager.js";
12
17
  import { Mailbox } from "./mailbox.js";
13
18
  import { TeamTaskStore } from "./teamTaskStore.js";
14
19
  import {
15
20
  spawnTeammate,
16
21
  markTeammateIdle,
22
+ markTeammateCompleted,
17
23
  getTeamSummary
18
24
  } from "./teammateSpawner.js";
25
+ import { teamEvents } from "./teamEvents.js";
26
+ import { MessageInjectionChannel } from "./injectionChannel.js";
27
+ import { AgentHeartbeat } from "./heartbeat.js";
28
+ import {
29
+ formatTeamMessage,
30
+ formatTeamMessagesForInjection,
31
+ formatUserGuidanceForInjection,
32
+ formatIdleNotificationForInjection,
33
+ parseIdleNotification
34
+ } from "./messageFormatter.js";
35
+ import { resolveBackend } from "./backends/resolver.js";
36
+ import { TmuxBackend } from "./backends/tmux.js";
37
+ import { InProcessBackend } from "./backends/inProcess.js";
38
+ function safeQuote(s) {
39
+ return `'${s.replace(/'/g, "'\\''")}'`;
40
+ }
19
41
  export {
42
+ AgentHeartbeat,
43
+ InProcessBackend,
20
44
  Mailbox,
45
+ MessageInjectionChannel,
21
46
  TeamTaskStore,
47
+ TmuxBackend,
22
48
  addTeammate,
23
49
  createTeam,
50
+ disbandAllTeams,
24
51
  disbandTeam,
52
+ formatIdleNotificationForInjection,
53
+ formatTeamMessage,
54
+ formatTeamMessagesForInjection,
55
+ formatUserGuidanceForInjection,
25
56
  getActiveTeams,
26
57
  getTeam,
27
58
  getTeamSummary,
28
59
  isAgentTeamsEnabled,
29
60
  loadTeam,
61
+ markTeammateCompleted,
30
62
  markTeammateIdle,
63
+ parseIdleNotification,
64
+ registerAgentAbortController,
65
+ resolveBackend,
31
66
  resolveDisplayMode,
67
+ safeQuote,
68
+ sanitizeTeamName,
32
69
  spawnTeammate,
33
- updateTeammateStatus
70
+ teamEvents,
71
+ unregisterAgentAbortController,
72
+ updateTeammateStatus,
73
+ updateTeammateWorktree
34
74
  };
35
75
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/services/agentTeams/index.ts"],
4
- "sourcesContent": ["/**\n * Agent Teams Module\n *\n * Multi-agent collaboration with message-based coordination.\n * Experimental: Enable with MINTO_EXPERIMENTAL_AGENT_TEAMS=1\n */\n\nexport {\n isAgentTeamsEnabled,\n createTeam,\n addTeammate,\n updateTeammateStatus,\n getTeam,\n getActiveTeams,\n disbandTeam,\n loadTeam,\n resolveDisplayMode,\n} from './teamManager'\n\nexport { Mailbox } from './mailbox'\nexport { TeamTaskStore } from './teamTaskStore'\nexport {\n spawnTeammate,\n markTeammateIdle,\n getTeamSummary,\n} from './teammateSpawner'\n"],
5
- "mappings": "AAOA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;",
4
+ "sourcesContent": ["/**\n * Agent Teams Module\n *\n * Multi-agent collaboration with message-based coordination.\n * Enabled by default. Disable with MINTO_EXPERIMENTAL_AGENT_TEAMS=0\n */\n\nexport {\n isAgentTeamsEnabled,\n sanitizeTeamName,\n createTeam,\n addTeammate,\n updateTeammateStatus,\n getTeam,\n getActiveTeams,\n disbandTeam,\n disbandAllTeams,\n loadTeam,\n resolveDisplayMode,\n registerAgentAbortController,\n unregisterAgentAbortController,\n updateTeammateWorktree,\n} from './teamManager'\n\nexport { Mailbox } from './mailbox'\nexport { TeamTaskStore } from './teamTaskStore'\nexport {\n spawnTeammate,\n markTeammateIdle,\n markTeammateCompleted,\n getTeamSummary,\n} from './teammateSpawner'\n\nexport { teamEvents } from './teamEvents'\nexport type { MemberStatusChangeData, TeamChangeData } from './teamEvents'\n\n// Message injection infrastructure\nexport { MessageInjectionChannel } from './injectionChannel'\nexport type { InjectionSource, InjectedMessage } from './injectionChannel'\n\nexport { AgentHeartbeat } from './heartbeat'\n\nexport {\n formatTeamMessage,\n formatTeamMessagesForInjection,\n formatUserGuidanceForInjection,\n formatIdleNotificationForInjection,\n parseIdleNotification,\n} from './messageFormatter'\nexport type { IdleNotificationData } from './messageFormatter'\n\n// DisplayBackend abstractions\nexport { resolveBackend } from './backends/resolver'\nexport { TmuxBackend } from './backends/tmux'\nexport { InProcessBackend } from './backends/inProcess'\nexport type {\n DisplayBackend,\n AgentHandle,\n SpawnOptions,\n} from './backends/types'\n\n/**\n * POSIX-safe single-quote escaping for shell arguments.\n * Prevents shell injection when passing args through tmux or other shells.\n */\nexport function safeQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`\n}\n"],
5
+ "mappings": "AAOA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,kBAAkB;AAI3B,SAAS,+BAA+B;AAGxC,SAAS,sBAAsB;AAE/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP,SAAS,sBAAsB;AAC/B,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB;AAW1B,SAAS,UAAU,GAAmB;AAC3C,SAAO,IAAI,EAAE,QAAQ,MAAM,OAAO,CAAC;AACrC;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,105 @@
1
+ class MessageInjectionChannel {
2
+ queue = [];
3
+ listeners = [];
4
+ /** Bounded set of processed message IDs to prevent double delivery */
5
+ processedIds = /* @__PURE__ */ new Set();
6
+ static MAX_PROCESSED_IDS = 500;
7
+ /**
8
+ * Push a message into the channel.
9
+ * Fires onMessage callbacks to notify listeners of new messages.
10
+ * @param displayText Optional original user text for visual queue display
11
+ * @param messageId Optional unique ID for deduplication (heartbeat + subscription)
12
+ */
13
+ push(text, source, displayText, messageId) {
14
+ if (messageId) {
15
+ if (this.processedIds.has(messageId)) return;
16
+ this.processedIds.add(messageId);
17
+ if (this.processedIds.size > MessageInjectionChannel.MAX_PROCESSED_IDS) {
18
+ const iter = this.processedIds.values();
19
+ for (let i = 0; i < 100; i++) iter.next();
20
+ const toDelete = [];
21
+ const entries = [...this.processedIds];
22
+ for (let i = 0; i < 100 && i < entries.length; i++) {
23
+ toDelete.push(entries[i]);
24
+ }
25
+ for (const id of toDelete) this.processedIds.delete(id);
26
+ }
27
+ }
28
+ const msg = {
29
+ text,
30
+ source,
31
+ timestamp: Date.now(),
32
+ displayText
33
+ };
34
+ this.queue.push(msg);
35
+ for (const cb of this.listeners) {
36
+ try {
37
+ cb(msg);
38
+ } catch {
39
+ }
40
+ }
41
+ }
42
+ /**
43
+ * Drain all messages from the channel, clearing the queue.
44
+ * Returns messages in insertion order.
45
+ */
46
+ drain() {
47
+ if (this.queue.length === 0) return [];
48
+ const messages = this.queue.splice(0);
49
+ return messages;
50
+ }
51
+ /**
52
+ * Check if there are pending messages without draining.
53
+ */
54
+ hasMessages() {
55
+ return this.queue.length > 0;
56
+ }
57
+ /**
58
+ * Number of pending messages.
59
+ */
60
+ get size() {
61
+ return this.queue.length;
62
+ }
63
+ /**
64
+ * Register a callback for when new messages are pushed.
65
+ * Returns an unsubscribe function.
66
+ */
67
+ onMessage(cb) {
68
+ this.listeners.push(cb);
69
+ return () => {
70
+ const idx = this.listeners.indexOf(cb);
71
+ if (idx >= 0) this.listeners.splice(idx, 1);
72
+ };
73
+ }
74
+ /**
75
+ * Peek at display texts of user-sourced messages without draining.
76
+ * Used by PromptInput to sync visual queue when switching focused agents.
77
+ */
78
+ peekUserDisplayTexts() {
79
+ return this.queue.filter((m) => m.source === "user" && m.displayText).map((m) => m.displayText);
80
+ }
81
+ /**
82
+ * Remove the last user-sourced message from the queue (for editing support).
83
+ * Returns the displayText (or raw text) of the removed message, or undefined if none found.
84
+ */
85
+ removeLastUserMessage() {
86
+ for (let i = this.queue.length - 1; i >= 0; i--) {
87
+ if (this.queue[i].source === "user") {
88
+ const msg = this.queue.splice(i, 1)[0];
89
+ return msg.displayText ?? msg.text;
90
+ }
91
+ }
92
+ return void 0;
93
+ }
94
+ /**
95
+ * Remove all pending messages and listeners.
96
+ */
97
+ dispose() {
98
+ this.queue.length = 0;
99
+ this.listeners.length = 0;
100
+ }
101
+ }
102
+ export {
103
+ MessageInjectionChannel
104
+ };
105
+ //# sourceMappingURL=injectionChannel.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/services/agentTeams/injectionChannel.ts"],
4
+ "sourcesContent": ["/**\n * Message Injection Channel\n *\n * Accumulates messages from multiple sources (team mailbox, user guidance,\n * task notifications) and provides a drain interface for the REPL's query loop.\n *\n * Messages are pushed by:\n * - AgentHeartbeat (team messages from mailbox)\n * - PromptInput (user guidance during active query)\n * - Task notifications (teammate idle/complete events)\n *\n * Messages are consumed by:\n * - REPL.tsx between query turns (drain + inject as user messages)\n * - REPL.tsx after query completion (drain + re-enter if messages found)\n * - REPL.tsx event-driven re-query (triggered by onMessage callback)\n */\n\nexport type InjectionSource = 'team' | 'user' | 'task'\n\nexport interface InjectedMessage {\n text: string\n source: InjectionSource\n timestamp: number\n /** Original user-facing text before XML formatting (for visual queue display) */\n displayText?: string\n}\n\ntype MessageCallback = (msg: InjectedMessage) => void\n\nexport class MessageInjectionChannel {\n private queue: InjectedMessage[] = []\n private listeners: MessageCallback[] = []\n /** Bounded set of processed message IDs to prevent double delivery */\n private processedIds = new Set<string>()\n private static readonly MAX_PROCESSED_IDS = 500\n\n /**\n * Push a message into the channel.\n * Fires onMessage callbacks to notify listeners of new messages.\n * @param displayText Optional original user text for visual queue display\n * @param messageId Optional unique ID for deduplication (heartbeat + subscription)\n */\n push(\n text: string,\n source: InjectionSource,\n displayText?: string,\n messageId?: string,\n ): void {\n // Deduplicate by messageId if provided\n if (messageId) {\n if (this.processedIds.has(messageId)) return\n this.processedIds.add(messageId)\n // Prune oldest entries when set grows too large\n if (this.processedIds.size > MessageInjectionChannel.MAX_PROCESSED_IDS) {\n const iter = this.processedIds.values()\n for (let i = 0; i < 100; i++) iter.next()\n // Delete first 100 entries\n const toDelete: string[] = []\n const entries = [...this.processedIds]\n for (let i = 0; i < 100 && i < entries.length; i++) {\n toDelete.push(entries[i]!)\n }\n for (const id of toDelete) this.processedIds.delete(id)\n }\n }\n\n const msg: InjectedMessage = {\n text,\n source,\n timestamp: Date.now(),\n displayText,\n }\n this.queue.push(msg)\n\n // Notify listeners (e.g. REPL idle re-query)\n for (const cb of this.listeners) {\n try {\n cb(msg)\n } catch {\n // Don't let listener errors break the channel\n }\n }\n }\n\n /**\n * Drain all messages from the channel, clearing the queue.\n * Returns messages in insertion order.\n */\n drain(): InjectedMessage[] {\n if (this.queue.length === 0) return []\n const messages = this.queue.splice(0)\n return messages\n }\n\n /**\n * Check if there are pending messages without draining.\n */\n hasMessages(): boolean {\n return this.queue.length > 0\n }\n\n /**\n * Number of pending messages.\n */\n get size(): number {\n return this.queue.length\n }\n\n /**\n * Register a callback for when new messages are pushed.\n * Returns an unsubscribe function.\n */\n onMessage(cb: MessageCallback): () => void {\n this.listeners.push(cb)\n return () => {\n const idx = this.listeners.indexOf(cb)\n if (idx >= 0) this.listeners.splice(idx, 1)\n }\n }\n\n /**\n * Peek at display texts of user-sourced messages without draining.\n * Used by PromptInput to sync visual queue when switching focused agents.\n */\n peekUserDisplayTexts(): string[] {\n return this.queue\n .filter(m => m.source === 'user' && m.displayText)\n .map(m => m.displayText!)\n }\n\n /**\n * Remove the last user-sourced message from the queue (for editing support).\n * Returns the displayText (or raw text) of the removed message, or undefined if none found.\n */\n removeLastUserMessage(): string | undefined {\n for (let i = this.queue.length - 1; i >= 0; i--) {\n if (this.queue[i]!.source === 'user') {\n const msg = this.queue.splice(i, 1)[0]!\n return msg.displayText ?? msg.text\n }\n }\n return undefined\n }\n\n /**\n * Remove all pending messages and listeners.\n */\n dispose(): void {\n this.queue.length = 0\n this.listeners.length = 0\n }\n}\n"],
5
+ "mappings": "AA6BO,MAAM,wBAAwB;AAAA,EAC3B,QAA2B,CAAC;AAAA,EAC5B,YAA+B,CAAC;AAAA;AAAA,EAEhC,eAAe,oBAAI,IAAY;AAAA,EACvC,OAAwB,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ5C,KACE,MACA,QACA,aACA,WACM;AAEN,QAAI,WAAW;AACb,UAAI,KAAK,aAAa,IAAI,SAAS,EAAG;AACtC,WAAK,aAAa,IAAI,SAAS;AAE/B,UAAI,KAAK,aAAa,OAAO,wBAAwB,mBAAmB;AACtE,cAAM,OAAO,KAAK,aAAa,OAAO;AACtC,iBAAS,IAAI,GAAG,IAAI,KAAK,IAAK,MAAK,KAAK;AAExC,cAAM,WAAqB,CAAC;AAC5B,cAAM,UAAU,CAAC,GAAG,KAAK,YAAY;AACrC,iBAAS,IAAI,GAAG,IAAI,OAAO,IAAI,QAAQ,QAAQ,KAAK;AAClD,mBAAS,KAAK,QAAQ,CAAC,CAAE;AAAA,QAC3B;AACA,mBAAW,MAAM,SAAU,MAAK,aAAa,OAAO,EAAE;AAAA,MACxD;AAAA,IACF;AAEA,UAAM,MAAuB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA,WAAW,KAAK,IAAI;AAAA,MACpB;AAAA,IACF;AACA,SAAK,MAAM,KAAK,GAAG;AAGnB,eAAW,MAAM,KAAK,WAAW;AAC/B,UAAI;AACF,WAAG,GAAG;AAAA,MACR,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAA2B;AACzB,QAAI,KAAK,MAAM,WAAW,EAAG,QAAO,CAAC;AACrC,UAAM,WAAW,KAAK,MAAM,OAAO,CAAC;AACpC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,cAAuB;AACrB,WAAO,KAAK,MAAM,SAAS;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe;AACjB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,IAAiC;AACzC,SAAK,UAAU,KAAK,EAAE;AACtB,WAAO,MAAM;AACX,YAAM,MAAM,KAAK,UAAU,QAAQ,EAAE;AACrC,UAAI,OAAO,EAAG,MAAK,UAAU,OAAO,KAAK,CAAC;AAAA,IAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAiC;AAC/B,WAAO,KAAK,MACT,OAAO,OAAK,EAAE,WAAW,UAAU,EAAE,WAAW,EAChD,IAAI,OAAK,EAAE,WAAY;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,wBAA4C;AAC1C,aAAS,IAAI,KAAK,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;AAC/C,UAAI,KAAK,MAAM,CAAC,EAAG,WAAW,QAAQ;AACpC,cAAM,MAAM,KAAK,MAAM,OAAO,GAAG,CAAC,EAAE,CAAC;AACrC,eAAO,IAAI,eAAe,IAAI;AAAA,MAChC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,SAAK,MAAM,SAAS;AACpB,SAAK,UAAU,SAAS;AAAA,EAC1B;AACF;",
6
+ "names": []
7
+ }