@within-7/minto 0.4.1 → 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,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/services/agentTeams/messageFormatter.ts"],
4
+ "sourcesContent": ["/**\n * Agent Teams Message Formatter\n *\n * Shared XML formatting helpers for consistent message injection\n * across REPL, TaskTool, headless agents, and heartbeat.\n *\n * All injection points use the CC-compatible `<team-message>` tag format.\n */\n\nimport type { TeamMessage } from '../../types/agentTeams'\n\n/**\n * Sanitize team message text to prevent injection attacks.\n * Replaces XML tags that could break message envelopes or forge system instructions.\n */\nexport function sanitizeTeamMessageText(text: string): string {\n return (\n text\n // Prevent envelope breakout\n .replace(/<\\/team-message>/gi, '[team-message-close]')\n // Prevent system instruction forgery\n .replace(/<system-reminder>/gi, '[system-reminder-open]')\n .replace(/<\\/system-reminder>/gi, '[system-reminder-close]')\n // Prevent API protocol injection\n .replace(/<tool_use>/gi, '[tool-use-open]')\n .replace(/<\\/tool_use>/gi, '[tool-use-close]')\n .replace(/<tool_result>/gi, '[tool-result-open]')\n .replace(/<\\/tool_result>/gi, '[tool-result-close]')\n // Prevent opening tag injection (with potential attributes)\n .replace(/<team-message\\b/gi, '[team-message-open')\n // Prevent user guidance injection\n .replace(/<user-guidance>/gi, '[user-guidance-open]')\n .replace(/<\\/user-guidance>/gi, '[user-guidance-close]')\n // Prevent task notification injection\n .replace(/<task-notification>/gi, '[task-notification-open]')\n .replace(/<\\/task-notification>/gi, '[task-notification-close]')\n // Prevent skill injection\n .replace(/<preloaded-skill>/gi, '[preloaded-skill-open]')\n .replace(/<\\/preloaded-skill>/gi, '[preloaded-skill-close]')\n )\n}\n\n/**\n * Data extracted from idle notification JSON messages\n */\nexport interface IdleNotificationData {\n agentName: string\n status: 'idle' | 'completed' | 'failed'\n taskId?: string\n message?: string\n summary?: string\n}\n\n/**\n * Format a single team message as CC-compatible XML.\n *\n * Output:\n * ```xml\n * <team-message from=\"researcher\" color=\"cyan\" summary=\"Found 5 files\">\n * {message text}\n * </team-message>\n * ```\n */\nexport function formatTeamMessage(msg: TeamMessage): string {\n const senderName = msg.from.split('@')[0] || msg.from\n const summaryText = msg.summary || msg.text.slice(0, 60).replace(/\"/g, \"'\")\n const colorAttr = msg.color ? ` color=\"${msg.color}\"` : ''\n const sanitizedText = sanitizeTeamMessageText(msg.text)\n return `<team-message from=\"${senderName}\"${colorAttr} summary=\"${summaryText}\">\\n${sanitizedText}\\n</team-message>`\n}\n\n/**\n * Format multiple team messages for injection into a conversation turn.\n * Returns a single string with all messages separated by double newlines.\n */\nexport function formatTeamMessagesForInjection(\n messages: TeamMessage[],\n): string {\n return messages.map(formatTeamMessage).join('\\n\\n')\n}\n\n/**\n * Format user guidance for injection when user types during a running query.\n *\n * Output:\n * ```xml\n * <user-guidance>\n * {user's input text}\n * </user-guidance>\n * ```\n */\nexport function formatUserGuidanceForInjection(input: string): string {\n const sanitizedInput = sanitizeTeamMessageText(input)\n return `<user-guidance>\\n${sanitizedInput}\\n</user-guidance>`\n}\n\n/**\n * Format an idle/task notification for injection.\n *\n * Output:\n * ```xml\n * <task-notification>\n * <task-id>{taskId}</task-id>\n * <status>{status}</status>\n * <message>{message}</message>\n * </task-notification>\n * ```\n */\nexport function formatIdleNotificationForInjection(\n notification: IdleNotificationData,\n): string {\n const parts = ['<task-notification>']\n if (notification.taskId) {\n parts.push(` <task-id>${notification.taskId}</task-id>`)\n }\n parts.push(` <status>${notification.status}</status>`)\n parts.push(\n ` <message>${notification.message || `Teammate \"${notification.agentName}\" is now ${notification.status}.`}</message>`,\n )\n if (notification.summary) {\n parts.push(` <summary>${notification.summary}</summary>`)\n }\n parts.push('</task-notification>')\n return parts.join('\\n')\n}\n\n/**\n * Try to parse a message as an idle notification JSON.\n * Returns parsed data if successful, null otherwise.\n */\n/**\n * Protocol message type \u2192 human-friendly summary mapping.\n */\nconst PROTOCOL_SUMMARIES: Record<string, string> = {\n shutdown_approved: 'Shutdown approved',\n shutdown_rejected: 'Shutdown rejected',\n shutdown_request: 'Shutdown requested',\n plan_approved: 'Plan approved',\n plan_rejected: 'Plan rejected',\n plan_approval_request: 'Plan review requested',\n}\n\n/**\n * Try to convert a protocol JSON message to a human-friendly summary.\n * Returns the friendly string, or null if not a protocol message.\n */\nexport function humanizeProtocolMessage(text: string): string | null {\n try {\n const parsed = JSON.parse(text)\n if (\n parsed &&\n typeof parsed === 'object' &&\n parsed.type in PROTOCOL_SUMMARIES\n ) {\n return PROTOCOL_SUMMARIES[parsed.type] || parsed.type\n }\n } catch {\n /* not JSON */\n }\n return null\n}\n\nexport function parseIdleNotification(\n text: string,\n): IdleNotificationData | null {\n try {\n const parsed = JSON.parse(text)\n if (\n parsed &&\n typeof parsed === 'object' &&\n (parsed.type === 'idle_notification' ||\n parsed.type === 'task_completed' ||\n parsed.type === 'idle')\n ) {\n return {\n agentName: parsed.agentName || parsed.from || 'unknown',\n status: parsed.status || parsed.completedStatus || 'idle',\n taskId: parsed.taskId,\n message: parsed.message,\n summary: parsed.summary,\n }\n }\n } catch {\n // Not JSON \u2014 regular text message\n }\n return null\n}\n"],
5
+ "mappings": "AAeO,SAAS,wBAAwB,MAAsB;AAC5D,SACE,KAEG,QAAQ,sBAAsB,sBAAsB,EAEpD,QAAQ,uBAAuB,wBAAwB,EACvD,QAAQ,yBAAyB,yBAAyB,EAE1D,QAAQ,gBAAgB,iBAAiB,EACzC,QAAQ,kBAAkB,kBAAkB,EAC5C,QAAQ,mBAAmB,oBAAoB,EAC/C,QAAQ,qBAAqB,qBAAqB,EAElD,QAAQ,qBAAqB,oBAAoB,EAEjD,QAAQ,qBAAqB,sBAAsB,EACnD,QAAQ,uBAAuB,uBAAuB,EAEtD,QAAQ,yBAAyB,0BAA0B,EAC3D,QAAQ,2BAA2B,2BAA2B,EAE9D,QAAQ,uBAAuB,wBAAwB,EACvD,QAAQ,yBAAyB,yBAAyB;AAEjE;AAuBO,SAAS,kBAAkB,KAA0B;AAC1D,QAAM,aAAa,IAAI,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI;AACjD,QAAM,cAAc,IAAI,WAAW,IAAI,KAAK,MAAM,GAAG,EAAE,EAAE,QAAQ,MAAM,GAAG;AAC1E,QAAM,YAAY,IAAI,QAAQ,WAAW,IAAI,KAAK,MAAM;AACxD,QAAM,gBAAgB,wBAAwB,IAAI,IAAI;AACtD,SAAO,uBAAuB,UAAU,IAAI,SAAS,aAAa,WAAW;AAAA,EAAO,aAAa;AAAA;AACnG;AAMO,SAAS,+BACd,UACQ;AACR,SAAO,SAAS,IAAI,iBAAiB,EAAE,KAAK,MAAM;AACpD;AAYO,SAAS,+BAA+B,OAAuB;AACpE,QAAM,iBAAiB,wBAAwB,KAAK;AACpD,SAAO;AAAA,EAAoB,cAAc;AAAA;AAC3C;AAcO,SAAS,mCACd,cACQ;AACR,QAAM,QAAQ,CAAC,qBAAqB;AACpC,MAAI,aAAa,QAAQ;AACvB,UAAM,KAAK,cAAc,aAAa,MAAM,YAAY;AAAA,EAC1D;AACA,QAAM,KAAK,aAAa,aAAa,MAAM,WAAW;AACtD,QAAM;AAAA,IACJ,cAAc,aAAa,WAAW,aAAa,aAAa,SAAS,YAAY,aAAa,MAAM,GAAG;AAAA,EAC7G;AACA,MAAI,aAAa,SAAS;AACxB,UAAM,KAAK,cAAc,aAAa,OAAO,YAAY;AAAA,EAC3D;AACA,QAAM,KAAK,sBAAsB;AACjC,SAAO,MAAM,KAAK,IAAI;AACxB;AASA,MAAM,qBAA6C;AAAA,EACjD,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,uBAAuB;AACzB;AAMO,SAAS,wBAAwB,MAA6B;AACnE,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,QACE,UACA,OAAO,WAAW,YAClB,OAAO,QAAQ,oBACf;AACA,aAAO,mBAAmB,OAAO,IAAI,KAAK,OAAO;AAAA,IACnD;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAEO,SAAS,sBACd,MAC6B;AAC7B,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,QACE,UACA,OAAO,WAAW,aACjB,OAAO,SAAS,uBACf,OAAO,SAAS,oBAChB,OAAO,SAAS,SAClB;AACA,aAAO;AAAA,QACL,WAAW,OAAO,aAAa,OAAO,QAAQ;AAAA,QAC9C,QAAQ,OAAO,UAAU,OAAO,mBAAmB;AAAA,QACnD,QAAQ,OAAO;AAAA,QACf,SAAS,OAAO;AAAA,QAChB,SAAS,OAAO;AAAA,MAClB;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,71 @@
1
+ async function delegatePermissionToLead(options) {
2
+ const {
3
+ teamName,
4
+ agentId,
5
+ toolName,
6
+ toolUseId,
7
+ input,
8
+ description,
9
+ permissionSuggestions
10
+ } = options;
11
+ let mailbox;
12
+ try {
13
+ const { getTeam } = require("./teamManager");
14
+ const entry = getTeam(teamName);
15
+ if (!entry?.mailbox) {
16
+ return { approved: false, error: "Team not found or mailbox unavailable" };
17
+ }
18
+ mailbox = entry.mailbox;
19
+ } catch {
20
+ return { approved: false, error: "Failed to access team mailbox" };
21
+ }
22
+ const requestId = `perm-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
23
+ const leadId = `team-lead@${teamName}`;
24
+ const request = JSON.stringify({
25
+ type: "permission_request",
26
+ request_id: requestId,
27
+ agent_id: agentId,
28
+ tool_name: toolName,
29
+ tool_use_id: toolUseId,
30
+ description,
31
+ input,
32
+ permission_suggestions: permissionSuggestions ?? [],
33
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
34
+ });
35
+ mailbox.send(agentId, leadId, request, {
36
+ summary: `Permission request: ${toolName}`
37
+ });
38
+ const POLL_INTERVAL = 500;
39
+ const TIMEOUT = 12e4;
40
+ const startTime = Date.now();
41
+ while (Date.now() - startTime < TIMEOUT) {
42
+ await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
43
+ const messages = mailbox.getUnread(agentId);
44
+ for (const msg of messages) {
45
+ try {
46
+ const parsed = JSON.parse(msg.text);
47
+ if (parsed.type === "permission_response" && parsed.request_id === requestId) {
48
+ mailbox.markRead([msg.id]);
49
+ if (parsed.subtype === "success" || parsed.approved) {
50
+ return {
51
+ approved: true,
52
+ updatedInput: parsed.response?.updated_input ?? void 0,
53
+ permissionUpdates: parsed.response?.permission_updates ?? void 0
54
+ };
55
+ } else {
56
+ return {
57
+ approved: false,
58
+ error: parsed.error || "Permission denied by team lead"
59
+ };
60
+ }
61
+ }
62
+ } catch {
63
+ }
64
+ }
65
+ }
66
+ return { approved: false, error: "Permission request timed out (120s)" };
67
+ }
68
+ export {
69
+ delegatePermissionToLead
70
+ };
71
+ //# sourceMappingURL=permissionDelegation.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/services/agentTeams/permissionDelegation.ts"],
4
+ "sourcesContent": ["/**\n * Permission Delegation for Agent Teams\n *\n * Allows headless teammates to delegate permission decisions to the team lead\n * via the mailbox, instead of auto-denying tool usage.\n *\n * Flow:\n * 1. Teammate calls a tool that requires user permission\n * 2. Instead of auto-denying, teammate sends `permission_request` to leader's inbox\n * 3. Leader reviews and sends `permission_response` back via SendMessage\n * 4. Teammate blocks (polling) until response arrives, then proceeds or fails\n */\n\nimport type { Mailbox } from './mailbox'\n\nexport interface PermissionDelegationResult {\n approved: boolean\n updatedInput?: Record<string, unknown>\n permissionUpdates?: Record<string, unknown>\n error?: string\n}\n\n/**\n * Delegate a permission decision to the team lead via mailbox.\n * Sends a permission_request and polls for permission_response.\n *\n * @returns Result with approved status and optional updates from the leader\n */\nexport async function delegatePermissionToLead(options: {\n teamName: string\n agentId: string\n toolName: string\n toolUseId: string\n input: Record<string, unknown>\n description: string\n permissionSuggestions?: string[]\n}): Promise<PermissionDelegationResult> {\n const {\n teamName,\n agentId,\n toolName,\n toolUseId,\n input,\n description,\n permissionSuggestions,\n } = options\n\n // Get the team's mailbox\n let mailbox: Mailbox\n try {\n // Lazy require to avoid circular dependencies at module load time\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { getTeam } =\n require('./teamManager') as typeof import('./teamManager')\n const entry = getTeam(teamName)\n if (!entry?.mailbox) {\n return { approved: false, error: 'Team not found or mailbox unavailable' }\n }\n mailbox = entry.mailbox\n } catch {\n return { approved: false, error: 'Failed to access team mailbox' }\n }\n\n const requestId = `perm-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\n const leadId = `team-lead@${teamName}`\n\n // Send permission_request to the team leader\n const request = JSON.stringify({\n type: 'permission_request',\n request_id: requestId,\n agent_id: agentId,\n tool_name: toolName,\n tool_use_id: toolUseId,\n description,\n input,\n permission_suggestions: permissionSuggestions ?? [],\n timestamp: new Date().toISOString(),\n })\n\n mailbox.send(agentId, leadId, request, {\n summary: `Permission request: ${toolName}`,\n })\n\n // Poll for response with timeout\n const POLL_INTERVAL = 500 // ms\n const TIMEOUT = 120_000 // 2 minutes\n const startTime = Date.now()\n\n while (Date.now() - startTime < TIMEOUT) {\n await new Promise(resolve => setTimeout(resolve, POLL_INTERVAL))\n\n const messages = mailbox.getUnread(agentId)\n for (const msg of messages) {\n try {\n const parsed = JSON.parse(msg.text)\n if (\n parsed.type === 'permission_response' &&\n parsed.request_id === requestId\n ) {\n mailbox.markRead([msg.id])\n if (parsed.subtype === 'success' || parsed.approved) {\n return {\n approved: true,\n updatedInput: parsed.response?.updated_input ?? undefined,\n permissionUpdates:\n parsed.response?.permission_updates ?? undefined,\n }\n } else {\n return {\n approved: false,\n error: parsed.error || 'Permission denied by team lead',\n }\n }\n }\n } catch {\n // Not a JSON message or not our response \u2014 skip\n }\n }\n }\n\n return { approved: false, error: 'Permission request timed out (120s)' }\n}\n"],
5
+ "mappings": "AA4BA,eAAsB,yBAAyB,SAQP;AACtC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAGJ,MAAI;AACJ,MAAI;AAGF,UAAM,EAAE,QAAQ,IACd,QAAQ,eAAe;AACzB,UAAM,QAAQ,QAAQ,QAAQ;AAC9B,QAAI,CAAC,OAAO,SAAS;AACnB,aAAO,EAAE,UAAU,OAAO,OAAO,wCAAwC;AAAA,IAC3E;AACA,cAAU,MAAM;AAAA,EAClB,QAAQ;AACN,WAAO,EAAE,UAAU,OAAO,OAAO,gCAAgC;AAAA,EACnE;AAEA,QAAM,YAAY,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC9E,QAAM,SAAS,aAAa,QAAQ;AAGpC,QAAM,UAAU,KAAK,UAAU;AAAA,IAC7B,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,WAAW;AAAA,IACX,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA,wBAAwB,yBAAyB,CAAC;AAAA,IAClD,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC,CAAC;AAED,UAAQ,KAAK,SAAS,QAAQ,SAAS;AAAA,IACrC,SAAS,uBAAuB,QAAQ;AAAA,EAC1C,CAAC;AAGD,QAAM,gBAAgB;AACtB,QAAM,UAAU;AAChB,QAAM,YAAY,KAAK,IAAI;AAE3B,SAAO,KAAK,IAAI,IAAI,YAAY,SAAS;AACvC,UAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,aAAa,CAAC;AAE/D,UAAM,WAAW,QAAQ,UAAU,OAAO;AAC1C,eAAW,OAAO,UAAU;AAC1B,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,IAAI,IAAI;AAClC,YACE,OAAO,SAAS,yBAChB,OAAO,eAAe,WACtB;AACA,kBAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;AACzB,cAAI,OAAO,YAAY,aAAa,OAAO,UAAU;AACnD,mBAAO;AAAA,cACL,UAAU;AAAA,cACV,cAAc,OAAO,UAAU,iBAAiB;AAAA,cAChD,mBACE,OAAO,UAAU,sBAAsB;AAAA,YAC3C;AAAA,UACF,OAAO;AACL,mBAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO,OAAO,SAAS;AAAA,YACzB;AAAA,UACF;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,OAAO,OAAO,sCAAsC;AACzE;",
6
+ "names": []
7
+ }
@@ -0,0 +1,45 @@
1
+ import { EventEmitter } from "events";
2
+ class TeamEventEmitter extends EventEmitter {
3
+ static instance = null;
4
+ constructor() {
5
+ super();
6
+ this.setMaxListeners(20);
7
+ }
8
+ static getInstance() {
9
+ if (!TeamEventEmitter.instance) {
10
+ TeamEventEmitter.instance = new TeamEventEmitter();
11
+ }
12
+ return TeamEventEmitter.instance;
13
+ }
14
+ /**
15
+ * Emit member status change event
16
+ */
17
+ emitMemberStatusChange(data) {
18
+ this.emit("member:status", data);
19
+ }
20
+ /**
21
+ * Emit team lifecycle change event
22
+ */
23
+ emitTeamChange(data) {
24
+ this.emit("team:change", data);
25
+ }
26
+ /**
27
+ * Subscribe to member status changes
28
+ */
29
+ onMemberStatusChange(callback) {
30
+ this.on("member:status", callback);
31
+ return () => this.off("member:status", callback);
32
+ }
33
+ /**
34
+ * Subscribe to team lifecycle changes
35
+ */
36
+ onTeamChange(callback) {
37
+ this.on("team:change", callback);
38
+ return () => this.off("team:change", callback);
39
+ }
40
+ }
41
+ const teamEvents = TeamEventEmitter.getInstance();
42
+ export {
43
+ teamEvents
44
+ };
45
+ //# sourceMappingURL=teamEvents.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/services/agentTeams/teamEvents.ts"],
4
+ "sourcesContent": ["/**\n * Team Events\n *\n * Singleton EventEmitter for team lifecycle and member status changes.\n * Follows the same pattern as BackgroundAgentEventEmitter.\n *\n * Enables event-driven UI updates instead of polling.\n */\n\nimport { EventEmitter } from 'events'\nimport type { TeammateStatus } from '@minto-types/agentTeams'\n\nexport interface MemberStatusChangeData {\n teamName: string\n memberId: string\n memberName: string\n status: TeammateStatus\n previousStatus: TeammateStatus\n currentTaskId?: string\n}\n\nexport interface TeamChangeData {\n teamName: string\n event: 'created' | 'disbanded' | 'member_added'\n}\n\nclass TeamEventEmitter extends EventEmitter {\n private static instance: TeamEventEmitter | null = null\n\n private constructor() {\n super()\n this.setMaxListeners(20)\n }\n\n static getInstance(): TeamEventEmitter {\n if (!TeamEventEmitter.instance) {\n TeamEventEmitter.instance = new TeamEventEmitter()\n }\n return TeamEventEmitter.instance\n }\n\n /**\n * Emit member status change event\n */\n emitMemberStatusChange(data: MemberStatusChangeData): void {\n this.emit('member:status', data)\n }\n\n /**\n * Emit team lifecycle change event\n */\n emitTeamChange(data: TeamChangeData): void {\n this.emit('team:change', data)\n }\n\n /**\n * Subscribe to member status changes\n */\n onMemberStatusChange(\n callback: (data: MemberStatusChangeData) => void,\n ): () => void {\n this.on('member:status', callback)\n return () => this.off('member:status', callback)\n }\n\n /**\n * Subscribe to team lifecycle changes\n */\n onTeamChange(callback: (data: TeamChangeData) => void): () => void {\n this.on('team:change', callback)\n return () => this.off('team:change', callback)\n }\n}\n\nexport const teamEvents = TeamEventEmitter.getInstance()\n"],
5
+ "mappings": "AASA,SAAS,oBAAoB;AAiB7B,MAAM,yBAAyB,aAAa;AAAA,EAC1C,OAAe,WAAoC;AAAA,EAE3C,cAAc;AACpB,UAAM;AACN,SAAK,gBAAgB,EAAE;AAAA,EACzB;AAAA,EAEA,OAAO,cAAgC;AACrC,QAAI,CAAC,iBAAiB,UAAU;AAC9B,uBAAiB,WAAW,IAAI,iBAAiB;AAAA,IACnD;AACA,WAAO,iBAAiB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB,MAAoC;AACzD,SAAK,KAAK,iBAAiB,IAAI;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,MAA4B;AACzC,SAAK,KAAK,eAAe,IAAI;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,qBACE,UACY;AACZ,SAAK,GAAG,iBAAiB,QAAQ;AACjC,WAAO,MAAM,KAAK,IAAI,iBAAiB,QAAQ;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,UAAsD;AACjE,SAAK,GAAG,eAAe,QAAQ;AAC/B,WAAO,MAAM,KAAK,IAAI,eAAe,QAAQ;AAAA,EAC/C;AACF;AAEO,MAAM,aAAa,iBAAiB,YAAY;",
6
+ "names": []
7
+ }
@@ -1,22 +1,139 @@
1
- import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
1
+ import {
2
+ existsSync,
3
+ mkdirSync,
4
+ writeFileSync,
5
+ readFileSync,
6
+ unlinkSync
7
+ } from "fs";
8
+ import { randomUUID } from "crypto";
2
9
  import { join } from "path";
3
10
  import { homedir } from "os";
11
+ import { z } from "zod";
4
12
  import { Mailbox } from "./mailbox.js";
5
13
  import { TeamTaskStore } from "./teamTaskStore.js";
6
14
  import { emitReminderEvent } from "../systemReminder.js";
15
+ import { teamEvents } from "./teamEvents.js";
16
+ import { debug } from "../../utils/debugLogger.js";
17
+ const TeamConfigFileSchema = z.object({
18
+ name: z.string(),
19
+ description: z.string().optional().default(""),
20
+ createdAt: z.number(),
21
+ leadAgentId: z.string().optional(),
22
+ leadSessionId: z.string().optional().default(""),
23
+ displayMode: z.string().optional().default("auto"),
24
+ maxTeammates: z.number().optional().default(10),
25
+ members: z.array(
26
+ z.object({
27
+ agentId: z.string(),
28
+ name: z.string(),
29
+ agentType: z.string(),
30
+ color: z.string().nullable().optional(),
31
+ joinedAt: z.number().optional(),
32
+ tmuxPaneId: z.string().optional(),
33
+ cwd: z.string().optional(),
34
+ subscriptions: z.array(z.string()).optional(),
35
+ backendType: z.string().optional(),
36
+ worktreePath: z.string().nullable().optional(),
37
+ planModeRequired: z.boolean().optional(),
38
+ isActive: z.boolean().optional(),
39
+ mode: z.string().nullable().optional(),
40
+ status: z.string().optional(),
41
+ prompt: z.string().optional(),
42
+ currentTaskId: z.string().nullable().optional(),
43
+ lastActivity: z.number().nullable().optional(),
44
+ parentSessionId: z.string().nullable().optional()
45
+ })
46
+ ).optional().default([])
47
+ });
48
+ function sanitizeTeamName(name) {
49
+ return name.replace(/[^a-zA-Z0-9]/g, "-").toLowerCase();
50
+ }
7
51
  function isAgentTeamsEnabled() {
8
- return process.env.MINTO_EXPERIMENTAL_AGENT_TEAMS === "1";
52
+ if (process.env.MINTO_EXPERIMENTAL_AGENT_TEAMS === "0") return false;
53
+ if (process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "0") return false;
54
+ if (process.env.MINTO_EXPERIMENTAL_AGENT_TEAMS === "1") return true;
55
+ if (process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "1") return true;
56
+ try {
57
+ const { getGlobalConfig } = require("../../utils/config");
58
+ const config = getGlobalConfig();
59
+ if (config.enableAgentTeams === false) return false;
60
+ if (config.enableAgentTeams === true) return true;
61
+ } catch {
62
+ }
63
+ return true;
9
64
  }
10
65
  const activeTeams = /* @__PURE__ */ new Map();
66
+ const agentAbortControllers = /* @__PURE__ */ new Map();
67
+ function registerAgentAbortController(teamName, agentId, controller) {
68
+ agentAbortControllers.set(`${teamName}:${agentId}`, controller);
69
+ }
70
+ function unregisterAgentAbortController(teamName, agentId) {
71
+ agentAbortControllers.delete(`${teamName}:${agentId}`);
72
+ }
73
+ function abortTeamAgents(teamName) {
74
+ for (const [key, controller] of agentAbortControllers) {
75
+ if (key.startsWith(`${teamName}:`)) {
76
+ try {
77
+ controller.abort();
78
+ } catch {
79
+ }
80
+ agentAbortControllers.delete(key);
81
+ }
82
+ }
83
+ }
11
84
  function getTeamsDir() {
12
85
  return join(homedir(), ".minto", "teams");
13
86
  }
87
+ function persistTeam(teamDir, team) {
88
+ try {
89
+ const configData = {
90
+ name: team.name,
91
+ description: team.config.description || "",
92
+ createdAt: team.createdAt,
93
+ leadAgentId: `team-lead@${team.name}`,
94
+ leadSessionId: team.leadSessionId || "",
95
+ // Minto extensions
96
+ displayMode: team.config.displayMode || "auto",
97
+ maxTeammates: team.config.maxTeammates || 10,
98
+ members: team.members.map((m) => ({
99
+ // CC-compatible fields
100
+ agentId: m.id,
101
+ name: m.name,
102
+ agentType: m.agentType,
103
+ color: m.color || null,
104
+ joinedAt: m.joinedAt || m.lastActivity,
105
+ tmuxPaneId: m.tmuxPaneId || (m.backendType === "in-process" ? "in-process" : "unknown"),
106
+ cwd: m.cwd || process.cwd(),
107
+ subscriptions: m.subscriptions || [],
108
+ backendType: m.backendType || "in-process",
109
+ worktreePath: m.worktreePath || null,
110
+ planModeRequired: m.planModeRequired || false,
111
+ isActive: m.isActive !== false,
112
+ mode: m.mode || null,
113
+ // Minto extension fields
114
+ status: m.status || "idle",
115
+ prompt: m.prompt || "",
116
+ currentTaskId: m.currentTaskId || null,
117
+ lastActivity: m.lastActivity || null,
118
+ parentSessionId: m.parentSessionId || null
119
+ }))
120
+ };
121
+ writeFileSync(
122
+ join(teamDir, "config.json"),
123
+ JSON.stringify(configData, null, 2),
124
+ "utf-8"
125
+ );
126
+ } catch (error) {
127
+ debug.warn("TEAM_PERSIST_CONFIG_FAILED", { error });
128
+ }
129
+ }
14
130
  function createTeam(config) {
15
131
  if (!isAgentTeamsEnabled()) {
16
132
  throw new Error(
17
- "Agent Teams is experimental. Set MINTO_EXPERIMENTAL_AGENT_TEAMS=1 to enable."
133
+ "Agent Teams is disabled. Remove enableAgentTeams: false from config or unset MINTO_EXPERIMENTAL_AGENT_TEAMS=0 to re-enable."
18
134
  );
19
135
  }
136
+ config = { ...config, name: sanitizeTeamName(config.name) };
20
137
  if (activeTeams.has(config.name)) {
21
138
  throw new Error(`Team "${config.name}" already exists`);
22
139
  }
@@ -24,7 +141,8 @@ function createTeam(config) {
24
141
  name: config.name,
25
142
  config,
26
143
  members: [],
27
- createdAt: Date.now()
144
+ createdAt: Date.now(),
145
+ leadSessionId: randomUUID()
28
146
  };
29
147
  const mailbox = new Mailbox(config.name);
30
148
  const taskStore = new TeamTaskStore(config.name);
@@ -34,12 +152,9 @@ function createTeam(config) {
34
152
  if (!existsSync(teamDir)) {
35
153
  mkdirSync(teamDir, { recursive: true });
36
154
  }
37
- writeFileSync(
38
- join(teamDir, "team.json"),
39
- JSON.stringify(team, null, 2),
40
- "utf-8"
41
- );
155
+ persistTeam(teamDir, team);
42
156
  activeTeams.set(config.name, { team, mailbox, taskStore });
157
+ teamEvents.emitTeamChange({ teamName: config.name, event: "created" });
43
158
  emitReminderEvent("team:coordination", {
44
159
  teamId: config.name,
45
160
  message: `Team "${config.name}" created (max ${config.maxTeammates} teammates).`
@@ -51,6 +166,17 @@ function addTeammate(teamName, teammate) {
51
166
  if (!entry) {
52
167
  throw new Error(`Team "${teamName}" not found`);
53
168
  }
169
+ const activeMembers = entry.team.members.filter((m) => m.status !== "stopped");
170
+ if (activeMembers.length >= entry.team.config.maxTeammates) {
171
+ throw new Error(
172
+ `Team "${teamName}" has reached maximum members (${entry.team.config.maxTeammates})`
173
+ );
174
+ }
175
+ const existing = entry.team.members.find((m) => m.id === teammate.id);
176
+ if (existing) {
177
+ Object.assign(existing, teammate, { lastActivity: Date.now() });
178
+ return existing;
179
+ }
54
180
  const fullTeammate = {
55
181
  ...teammate,
56
182
  lastActivity: Date.now()
@@ -61,11 +187,8 @@ function addTeammate(teamName, teammate) {
61
187
  message: `Teammate "${teammate.id}" (${teammate.agentType}) joined team "${teamName}".`
62
188
  });
63
189
  const teamDir = join(getTeamsDir(), teamName);
64
- writeFileSync(
65
- join(teamDir, "team.json"),
66
- JSON.stringify(entry.team, null, 2),
67
- "utf-8"
68
- );
190
+ persistTeam(teamDir, entry.team);
191
+ teamEvents.emitTeamChange({ teamName, event: "member_added" });
69
192
  return fullTeammate;
70
193
  }
71
194
  function updateTeammateStatus(teamName, teammateId, status, currentTaskId) {
@@ -73,11 +196,40 @@ function updateTeammateStatus(teamName, teammateId, status, currentTaskId) {
73
196
  if (!entry) return;
74
197
  const member = entry.team.members.find((m) => m.id === teammateId);
75
198
  if (!member) return;
199
+ const previousStatus = member.status;
76
200
  member.status = status;
77
201
  member.lastActivity = Date.now();
78
202
  if (currentTaskId !== void 0) {
79
203
  member.currentTaskId = currentTaskId;
80
204
  }
205
+ teamEvents.emitMemberStatusChange({
206
+ teamName,
207
+ memberId: teammateId,
208
+ memberName: member.name,
209
+ status,
210
+ previousStatus,
211
+ currentTaskId
212
+ });
213
+ const significantTransitions = /* @__PURE__ */ new Set([
214
+ "idle",
215
+ "working",
216
+ "stopped",
217
+ "completed",
218
+ "failed"
219
+ ]);
220
+ if (previousStatus !== status && significantTransitions.has(status)) {
221
+ const teamDir = join(getTeamsDir(), teamName);
222
+ persistTeam(teamDir, entry.team);
223
+ }
224
+ }
225
+ function updateTeammateWorktree(teamName, teammateId, worktreePath) {
226
+ const entry = activeTeams.get(teamName);
227
+ if (!entry) return;
228
+ const member = entry.team.members.find((m) => m.id === teammateId);
229
+ if (!member) return;
230
+ member.worktreePath = worktreePath;
231
+ const teamDir = join(getTeamsDir(), teamName);
232
+ persistTeam(teamDir, entry.team);
81
233
  }
82
234
  function getTeam(teamName) {
83
235
  return activeTeams.get(teamName);
@@ -88,29 +240,84 @@ function getActiveTeams() {
88
240
  function disbandTeam(teamName) {
89
241
  const entry = activeTeams.get(teamName);
90
242
  if (!entry) return;
243
+ entry.mailbox.stopAllWatchers();
244
+ abortTeamAgents(teamName);
91
245
  for (const member of entry.team.members) {
92
246
  member.status = "stopped";
247
+ member.isActive = false;
93
248
  }
94
249
  const teamDir = join(getTeamsDir(), teamName);
95
250
  if (existsSync(teamDir)) {
96
- writeFileSync(
97
- join(teamDir, "team.json"),
98
- JSON.stringify(entry.team, null, 2),
99
- "utf-8"
100
- );
251
+ persistTeam(teamDir, entry.team);
101
252
  }
102
253
  activeTeams.delete(teamName);
254
+ teamEvents.emitTeamChange({ teamName, event: "disbanded" });
103
255
  emitReminderEvent("team:shutdown", {
104
256
  teamId: teamName,
105
257
  reason: "disbanded"
106
258
  });
107
259
  }
108
260
  function loadTeam(teamName) {
109
- const teamFile = join(getTeamsDir(), teamName, "team.json");
110
- if (!existsSync(teamFile)) return null;
261
+ const teamDir = join(getTeamsDir(), teamName);
262
+ const configFile = join(teamDir, "config.json");
263
+ const legacyFile = join(teamDir, "team.json");
264
+ if (!existsSync(configFile) && existsSync(legacyFile)) {
265
+ try {
266
+ const legacyContent = readFileSync(legacyFile, "utf-8");
267
+ const legacyTeam = JSON.parse(legacyContent);
268
+ persistTeam(teamDir, legacyTeam);
269
+ try {
270
+ unlinkSync(legacyFile);
271
+ } catch {
272
+ }
273
+ } catch {
274
+ return null;
275
+ }
276
+ }
277
+ if (!existsSync(configFile)) return null;
111
278
  try {
112
- const content = readFileSync(teamFile, "utf-8");
113
- const team = JSON.parse(content);
279
+ const content = readFileSync(configFile, "utf-8");
280
+ const rawData = JSON.parse(content);
281
+ const parsed = TeamConfigFileSchema.safeParse(rawData);
282
+ if (!parsed.success) {
283
+ debug.warn("TEAM_CONFIG_VALIDATION_FAILED", {
284
+ teamName,
285
+ error: parsed.error.message
286
+ });
287
+ return null;
288
+ }
289
+ const configData = parsed.data;
290
+ const team = {
291
+ name: configData.name,
292
+ config: {
293
+ name: configData.name,
294
+ displayMode: configData.displayMode || "auto",
295
+ maxTeammates: configData.maxTeammates || 10,
296
+ description: configData.description || ""
297
+ },
298
+ members: (configData.members || []).map((m) => ({
299
+ id: m.agentId,
300
+ name: m.name,
301
+ agentType: m.agentType,
302
+ status: m.status || "idle",
303
+ prompt: m.prompt || "",
304
+ currentTaskId: m.currentTaskId || void 0,
305
+ lastActivity: m.lastActivity || m.joinedAt,
306
+ color: m.color || void 0,
307
+ joinedAt: m.joinedAt,
308
+ backendType: m.backendType || "in-process",
309
+ tmuxPaneId: m.tmuxPaneId || void 0,
310
+ cwd: m.cwd || process.cwd(),
311
+ subscriptions: m.subscriptions || [],
312
+ worktreePath: m.worktreePath || void 0,
313
+ planModeRequired: m.planModeRequired || false,
314
+ isActive: m.isActive !== false,
315
+ mode: m.mode || void 0,
316
+ parentSessionId: m.parentSessionId || void 0
317
+ })),
318
+ createdAt: configData.createdAt,
319
+ leadSessionId: configData.leadSessionId || ""
320
+ };
114
321
  const mailbox = new Mailbox(teamName);
115
322
  const taskStore = new TeamTaskStore(teamName);
116
323
  mailbox.load();
@@ -121,29 +328,39 @@ function loadTeam(teamName) {
121
328
  return null;
122
329
  }
123
330
  }
124
- function resolveDisplayMode(mode) {
125
- if (mode === "tmux") return "tmux";
331
+ async function resolveDisplayMode(mode) {
126
332
  if (mode === "in-process") return "in-process";
127
- try {
128
- const { execSync } = require("child_process");
129
- execSync("which tmux", { stdio: "pipe" });
130
- if (process.env.TMUX) {
131
- return "tmux";
333
+ if (mode === "tmux") return "tmux";
334
+ if (mode === "aiter") return "aiter";
335
+ if (process.env.TMUX || process.env.TERM_PROGRAM === "iTerm.app") {
336
+ return "tmux";
337
+ }
338
+ return "in-process";
339
+ }
340
+ function disbandAllTeams() {
341
+ const teamNames = Array.from(activeTeams.keys());
342
+ for (const name of teamNames) {
343
+ try {
344
+ disbandTeam(name);
345
+ } catch (error) {
346
+ debug.warn("TEAM_DISBAND_CLEANUP_FAILED", { teamName: name, error });
132
347
  }
133
- return "in-process";
134
- } catch {
135
- return "in-process";
136
348
  }
137
349
  }
138
350
  export {
139
351
  addTeammate,
140
352
  createTeam,
353
+ disbandAllTeams,
141
354
  disbandTeam,
142
355
  getActiveTeams,
143
356
  getTeam,
144
357
  isAgentTeamsEnabled,
145
358
  loadTeam,
359
+ registerAgentAbortController,
146
360
  resolveDisplayMode,
147
- updateTeammateStatus
361
+ sanitizeTeamName,
362
+ unregisterAgentAbortController,
363
+ updateTeammateStatus,
364
+ updateTeammateWorktree
148
365
  };
149
366
  //# sourceMappingURL=teamManager.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/services/agentTeams/teamManager.ts"],
4
- "sourcesContent": ["/**\n * Team Manager\n *\n * Central coordinator for agent teams lifecycle.\n * Manages team creation, teammate spawning, and disbanding.\n *\n * Experimental: Enable with MINTO_EXPERIMENTAL_AGENT_TEAMS=1\n */\n\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, rmSync } from 'fs'\nimport { join } from 'path'\nimport { homedir } from 'os'\nimport type {\n Team,\n TeamConfig,\n Teammate,\n TeamDisplayMode,\n} from '../../types/agentTeams'\nimport { Mailbox } from './mailbox'\nimport { TeamTaskStore } from './teamTaskStore'\nimport { emitReminderEvent } from '../systemReminder'\n\n/**\n * Check if Agent Teams feature is enabled\n */\nexport function isAgentTeamsEnabled(): boolean {\n return process.env.MINTO_EXPERIMENTAL_AGENT_TEAMS === '1'\n}\n\n/**\n * Active teams registry\n */\nconst activeTeams = new Map<\n string,\n {\n team: Team\n mailbox: Mailbox\n taskStore: TeamTaskStore\n }\n>()\n\n/**\n * Get the teams storage directory\n */\nfunction getTeamsDir(): string {\n return join(homedir(), '.minto', 'teams')\n}\n\n/**\n * Create a new team\n */\nexport function createTeam(config: TeamConfig): Team {\n if (!isAgentTeamsEnabled()) {\n throw new Error(\n 'Agent Teams is experimental. Set MINTO_EXPERIMENTAL_AGENT_TEAMS=1 to enable.',\n )\n }\n\n if (activeTeams.has(config.name)) {\n throw new Error(`Team \"${config.name}\" already exists`)\n }\n\n const team: Team = {\n name: config.name,\n config,\n members: [],\n createdAt: Date.now(),\n }\n\n const mailbox = new Mailbox(config.name)\n const taskStore = new TeamTaskStore(config.name)\n taskStore.load()\n mailbox.load()\n\n // Persist team config\n const teamDir = join(getTeamsDir(), config.name)\n if (!existsSync(teamDir)) {\n mkdirSync(teamDir, { recursive: true })\n }\n writeFileSync(\n join(teamDir, 'team.json'),\n JSON.stringify(team, null, 2),\n 'utf-8',\n )\n\n activeTeams.set(config.name, { team, mailbox, taskStore })\n\n emitReminderEvent('team:coordination', {\n teamId: config.name,\n message: `Team \"${config.name}\" created (max ${config.maxTeammates} teammates).`,\n })\n\n return team\n}\n\n/**\n * Add a teammate to a team\n */\nexport function addTeammate(\n teamName: string,\n teammate: Omit<Teammate, 'lastActivity'>,\n): Teammate {\n const entry = activeTeams.get(teamName)\n if (!entry) {\n throw new Error(`Team \"${teamName}\" not found`)\n }\n\n const fullTeammate: Teammate = {\n ...teammate,\n lastActivity: Date.now(),\n }\n\n entry.team.members.push(fullTeammate)\n\n emitReminderEvent('team:coordination', {\n teamId: teamName,\n message: `Teammate \"${teammate.id}\" (${teammate.agentType}) joined team \"${teamName}\".`,\n })\n\n // Persist\n const teamDir = join(getTeamsDir(), teamName)\n writeFileSync(\n join(teamDir, 'team.json'),\n JSON.stringify(entry.team, null, 2),\n 'utf-8',\n )\n\n return fullTeammate\n}\n\n/**\n * Update teammate status\n */\nexport function updateTeammateStatus(\n teamName: string,\n teammateId: string,\n status: Teammate['status'],\n currentTaskId?: string,\n): void {\n const entry = activeTeams.get(teamName)\n if (!entry) return\n\n const member = entry.team.members.find(m => m.id === teammateId)\n if (!member) return\n\n member.status = status\n member.lastActivity = Date.now()\n if (currentTaskId !== undefined) {\n member.currentTaskId = currentTaskId\n }\n}\n\n/**\n * Get a team by name\n */\nexport function getTeam(\n teamName: string,\n): { team: Team; mailbox: Mailbox; taskStore: TeamTaskStore } | undefined {\n return activeTeams.get(teamName)\n}\n\n/**\n * Get all active teams\n */\nexport function getActiveTeams(): Team[] {\n return Array.from(activeTeams.values()).map(e => e.team)\n}\n\n/**\n * Disband a team\n */\nexport function disbandTeam(teamName: string): void {\n const entry = activeTeams.get(teamName)\n if (!entry) return\n\n // Mark all members as stopped\n for (const member of entry.team.members) {\n member.status = 'stopped'\n }\n\n // Persist final state\n const teamDir = join(getTeamsDir(), teamName)\n if (existsSync(teamDir)) {\n writeFileSync(\n join(teamDir, 'team.json'),\n JSON.stringify(entry.team, null, 2),\n 'utf-8',\n )\n }\n\n activeTeams.delete(teamName)\n\n emitReminderEvent('team:shutdown', {\n teamId: teamName,\n reason: 'disbanded',\n })\n}\n\n/**\n * Load a persisted team from disk\n */\nexport function loadTeam(teamName: string): Team | null {\n const teamFile = join(getTeamsDir(), teamName, 'team.json')\n if (!existsSync(teamFile)) return null\n\n try {\n const content = readFileSync(teamFile, 'utf-8')\n const team = JSON.parse(content) as Team\n\n const mailbox = new Mailbox(teamName)\n const taskStore = new TeamTaskStore(teamName)\n mailbox.load()\n taskStore.load()\n\n activeTeams.set(teamName, { team, mailbox, taskStore })\n return team\n } catch {\n return null\n }\n}\n\n/**\n * Resolve display mode based on config and environment\n */\nexport function resolveDisplayMode(\n mode: TeamDisplayMode,\n): 'in-process' | 'tmux' {\n if (mode === 'tmux') return 'tmux'\n if (mode === 'in-process') return 'in-process'\n\n // Auto: check if tmux is available\n try {\n const { execSync } = require('child_process')\n execSync('which tmux', { stdio: 'pipe' })\n // tmux available, check if we're already in a tmux session\n if (process.env.TMUX) {\n return 'tmux'\n }\n return 'in-process' // Default to in-process even if tmux available\n } catch {\n return 'in-process'\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Team Manager\n *\n * Central coordinator for agent teams lifecycle.\n * Manages team creation, teammate spawning, and disbanding.\n *\n * Enabled by default. Disable with MINTO_EXPERIMENTAL_AGENT_TEAMS=0\n * or set enableAgentTeams: false in global config.\n */\n\nimport {\n existsSync,\n mkdirSync,\n writeFileSync,\n readFileSync,\n rmSync,\n unlinkSync,\n} from 'fs'\nimport { randomUUID } from 'crypto'\nimport { join } from 'path'\nimport { homedir } from 'os'\nimport { z } from 'zod'\nimport type {\n Team,\n TeamConfig,\n Teammate,\n TeamDisplayMode,\n} from '../../types/agentTeams'\nimport { Mailbox } from './mailbox'\nimport { TeamTaskStore } from './teamTaskStore'\nimport { emitReminderEvent } from '../systemReminder'\nimport { teamEvents } from './teamEvents'\nimport { debug } from '../../utils/debugLogger'\n\n/** Zod schema for team config.json \u2014 used to validate JSON parsed from disk */\nconst TeamConfigFileSchema = z.object({\n name: z.string(),\n description: z.string().optional().default(''),\n createdAt: z.number(),\n leadAgentId: z.string().optional(),\n leadSessionId: z.string().optional().default(''),\n displayMode: z.string().optional().default('auto'),\n maxTeammates: z.number().optional().default(10),\n members: z\n .array(\n z.object({\n agentId: z.string(),\n name: z.string(),\n agentType: z.string(),\n color: z.string().nullable().optional(),\n joinedAt: z.number().optional(),\n tmuxPaneId: z.string().optional(),\n cwd: z.string().optional(),\n subscriptions: z.array(z.string()).optional(),\n backendType: z.string().optional(),\n worktreePath: z.string().nullable().optional(),\n planModeRequired: z.boolean().optional(),\n isActive: z.boolean().optional(),\n mode: z.string().nullable().optional(),\n status: z.string().optional(),\n prompt: z.string().optional(),\n currentTaskId: z.string().nullable().optional(),\n lastActivity: z.number().nullable().optional(),\n parentSessionId: z.string().nullable().optional(),\n }),\n )\n .optional()\n .default([]),\n})\n\nexport function sanitizeTeamName(name: string): string {\n return name.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase()\n}\n\n/**\n * Check if Agent Teams feature is enabled\n *\n * Enabled by default. Can be explicitly disabled via:\n * 1. GlobalConfig.enableAgentTeams === false\n * 2. MINTO_EXPERIMENTAL_AGENT_TEAMS=0 env var\n */\nexport function isAgentTeamsEnabled(): boolean {\n // Explicit disable takes highest priority (Minto > CC fallback)\n if (process.env.MINTO_EXPERIMENTAL_AGENT_TEAMS === '0') return false\n if (process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === '0') return false\n\n // Explicit enable (CC compat: CC uses =1 opt-in, Minto defaults to enabled)\n if (process.env.MINTO_EXPERIMENTAL_AGENT_TEAMS === '1') return true\n if (process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === '1') return true\n\n // Check config flag (lazy require to avoid circular deps at module load time)\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { getGlobalConfig } =\n require('../../utils/config') as typeof import('../../utils/config')\n const config = getGlobalConfig()\n if (config.enableAgentTeams === false) return false\n if (config.enableAgentTeams === true) return true\n } catch {\n // Config not available yet \u2014 default to enabled\n }\n\n // Default: enabled (Minto behavior, differs from CC which defaults to disabled)\n return true\n}\n\n/**\n * Active teams registry\n */\nconst activeTeams = new Map<\n string,\n {\n team: Team\n mailbox: Mailbox\n taskStore: TeamTaskStore\n }\n>()\n\n/**\n * Track AbortControllers for running agent tasks.\n * Key: `${teamName}:${agentId}`, Value: AbortController\n * Used to abort agent query loops when team is disbanded or interrupted.\n */\nconst agentAbortControllers = new Map<string, AbortController>()\n\n/**\n * Register an AbortController for a running agent task.\n * Called by TaskTool when starting an in-process agent query loop.\n */\nexport function registerAgentAbortController(\n teamName: string,\n agentId: string,\n controller: AbortController,\n): void {\n agentAbortControllers.set(`${teamName}:${agentId}`, controller)\n}\n\n/**\n * Unregister an agent's AbortController (e.g., when the agent completes).\n */\nexport function unregisterAgentAbortController(\n teamName: string,\n agentId: string,\n): void {\n agentAbortControllers.delete(`${teamName}:${agentId}`)\n}\n\n/**\n * Abort all running agents for a given team.\n */\nfunction abortTeamAgents(teamName: string): void {\n for (const [key, controller] of agentAbortControllers) {\n if (key.startsWith(`${teamName}:`)) {\n try {\n controller.abort()\n } catch {\n // Ignore abort errors\n }\n agentAbortControllers.delete(key)\n }\n }\n}\n\n/**\n * Get the teams storage directory\n */\nfunction getTeamsDir(): string {\n return join(homedir(), '.minto', 'teams')\n}\n\n/**\n * Persist team state to config.json (single source of truth).\n *\n * CC-compatible flat format with Minto extensions for full team state.\n * Replaces the previous dual-file (team.json + config.json) approach.\n */\nfunction persistTeam(teamDir: string, team: Team): void {\n try {\n const configData = {\n name: team.name,\n description: team.config.description || '',\n createdAt: team.createdAt,\n leadAgentId: `team-lead@${team.name}`,\n leadSessionId: team.leadSessionId || '',\n // Minto extensions\n displayMode: team.config.displayMode || 'auto',\n maxTeammates: team.config.maxTeammates || 10,\n members: team.members.map(m => ({\n // CC-compatible fields\n agentId: m.id,\n name: m.name,\n agentType: m.agentType,\n color: m.color || null,\n joinedAt: m.joinedAt || m.lastActivity,\n tmuxPaneId:\n m.tmuxPaneId ||\n (m.backendType === 'in-process' ? 'in-process' : 'unknown'),\n cwd: m.cwd || process.cwd(),\n subscriptions: m.subscriptions || [],\n backendType: m.backendType || 'in-process',\n worktreePath: m.worktreePath || null,\n planModeRequired: m.planModeRequired || false,\n isActive: m.isActive !== false,\n mode: m.mode || null,\n // Minto extension fields\n status: m.status || 'idle',\n prompt: m.prompt || '',\n currentTaskId: m.currentTaskId || null,\n lastActivity: m.lastActivity || null,\n parentSessionId: m.parentSessionId || null,\n })),\n }\n writeFileSync(\n join(teamDir, 'config.json'),\n JSON.stringify(configData, null, 2),\n 'utf-8',\n )\n } catch (error) {\n debug.warn('TEAM_PERSIST_CONFIG_FAILED', { error })\n }\n}\n\n/**\n * Create a new team\n */\nexport function createTeam(config: TeamConfig): Team {\n if (!isAgentTeamsEnabled()) {\n throw new Error(\n 'Agent Teams is disabled. Remove enableAgentTeams: false from config or unset MINTO_EXPERIMENTAL_AGENT_TEAMS=0 to re-enable.',\n )\n }\n\n config = { ...config, name: sanitizeTeamName(config.name) }\n\n if (activeTeams.has(config.name)) {\n throw new Error(`Team \"${config.name}\" already exists`)\n }\n\n const team: Team = {\n name: config.name,\n config,\n members: [],\n createdAt: Date.now(),\n leadSessionId: randomUUID(),\n }\n\n const mailbox = new Mailbox(config.name)\n const taskStore = new TeamTaskStore(config.name)\n taskStore.load()\n mailbox.load()\n\n // Persist team state to config.json\n const teamDir = join(getTeamsDir(), config.name)\n if (!existsSync(teamDir)) {\n mkdirSync(teamDir, { recursive: true })\n }\n persistTeam(teamDir, team)\n\n activeTeams.set(config.name, { team, mailbox, taskStore })\n\n teamEvents.emitTeamChange({ teamName: config.name, event: 'created' })\n\n emitReminderEvent('team:coordination', {\n teamId: config.name,\n message: `Team \"${config.name}\" created (max ${config.maxTeammates} teammates).`,\n })\n\n return team\n}\n\n/**\n * Add a teammate to a team\n */\nexport function addTeammate(\n teamName: string,\n teammate: Omit<Teammate, 'lastActivity'>,\n): Teammate {\n const entry = activeTeams.get(teamName)\n if (!entry) {\n throw new Error(`Team \"${teamName}\" not found`)\n }\n\n // Enforce maxTeammates limit (count only non-stopped members)\n const activeMembers = entry.team.members.filter(m => m.status !== 'stopped')\n if (activeMembers.length >= entry.team.config.maxTeammates) {\n throw new Error(\n `Team \"${teamName}\" has reached maximum members (${entry.team.config.maxTeammates})`,\n )\n }\n\n // Guard against duplicate member IDs (e.g., retry or re-spawn)\n const existing = entry.team.members.find(m => m.id === teammate.id)\n if (existing) {\n Object.assign(existing, teammate, { lastActivity: Date.now() })\n return existing\n }\n\n const fullTeammate: Teammate = {\n ...teammate,\n lastActivity: Date.now(),\n }\n\n entry.team.members.push(fullTeammate)\n\n emitReminderEvent('team:coordination', {\n teamId: teamName,\n message: `Teammate \"${teammate.id}\" (${teammate.agentType}) joined team \"${teamName}\".`,\n })\n\n // Persist\n const teamDir = join(getTeamsDir(), teamName)\n persistTeam(teamDir, entry.team)\n\n teamEvents.emitTeamChange({ teamName, event: 'member_added' })\n\n return fullTeammate\n}\n\n/**\n * Update teammate status\n */\nexport function updateTeammateStatus(\n teamName: string,\n teammateId: string,\n status: Teammate['status'],\n currentTaskId?: string,\n): void {\n const entry = activeTeams.get(teamName)\n if (!entry) return\n\n const member = entry.team.members.find(m => m.id === teammateId)\n if (!member) return\n\n const previousStatus = member.status\n member.status = status\n member.lastActivity = Date.now()\n if (currentTaskId !== undefined) {\n member.currentTaskId = currentTaskId\n }\n\n teamEvents.emitMemberStatusChange({\n teamName,\n memberId: teammateId,\n memberName: member.name,\n status,\n previousStatus,\n currentTaskId,\n })\n\n // Persist to disk for significant state transitions\n const significantTransitions = new Set([\n 'idle',\n 'working',\n 'stopped',\n 'completed',\n 'failed',\n ])\n if (previousStatus !== status && significantTransitions.has(status)) {\n const teamDir = join(getTeamsDir(), teamName)\n persistTeam(teamDir, entry.team)\n }\n}\n\n/**\n * Update a teammate's worktree path and persist to disk.\n * Called after creating a git worktree for a teammate agent.\n */\nexport function updateTeammateWorktree(\n teamName: string,\n teammateId: string,\n worktreePath: string,\n): void {\n const entry = activeTeams.get(teamName)\n if (!entry) return\n const member = entry.team.members.find(m => m.id === teammateId)\n if (!member) return\n member.worktreePath = worktreePath\n // Persist\n const teamDir = join(getTeamsDir(), teamName)\n persistTeam(teamDir, entry.team)\n}\n\n/**\n * Get a team by name\n */\nexport function getTeam(\n teamName: string,\n): { team: Team; mailbox: Mailbox; taskStore: TeamTaskStore } | undefined {\n return activeTeams.get(teamName)\n}\n\n/**\n * Get all active teams\n */\nexport function getActiveTeams(): Team[] {\n return Array.from(activeTeams.values()).map(e => e.team)\n}\n\n/**\n * Disband a team \u2014 aborts all running agents, marks members stopped, cleans up.\n */\nexport function disbandTeam(teamName: string): void {\n const entry = activeTeams.get(teamName)\n if (!entry) return\n\n // Clean up mailbox file watchers before aborting agents\n entry.mailbox.stopAllWatchers()\n\n // Abort all running agent query loops for this team\n abortTeamAgents(teamName)\n\n // Mark all members as stopped\n for (const member of entry.team.members) {\n member.status = 'stopped'\n member.isActive = false\n }\n\n // Persist final state\n const teamDir = join(getTeamsDir(), teamName)\n if (existsSync(teamDir)) {\n persistTeam(teamDir, entry.team)\n }\n\n // Delete from active teams BEFORE emitting the event.\n // Listeners (e.g. useTeamMembers) call getActiveTeams() in their handler,\n // so the team must already be removed to avoid stale data.\n activeTeams.delete(teamName)\n\n teamEvents.emitTeamChange({ teamName, event: 'disbanded' })\n\n emitReminderEvent('team:shutdown', {\n teamId: teamName,\n reason: 'disbanded',\n })\n}\n\n/**\n * Load a persisted team from disk.\n *\n * Reads from config.json (single source of truth).\n * One-time migration: if only team.json exists, migrates to config.json.\n */\nexport function loadTeam(teamName: string): Team | null {\n const teamDir = join(getTeamsDir(), teamName)\n const configFile = join(teamDir, 'config.json')\n const legacyFile = join(teamDir, 'team.json')\n\n // Backward-compat migration: team.json \u2192 config.json\n if (!existsSync(configFile) && existsSync(legacyFile)) {\n try {\n const legacyContent = readFileSync(legacyFile, 'utf-8')\n // Legacy format: best-effort parse, no strict validation\n const legacyTeam = JSON.parse(legacyContent) as Team\n persistTeam(teamDir, legacyTeam)\n // Remove legacy file after successful migration\n try {\n unlinkSync(legacyFile)\n } catch {\n /* best-effort */\n }\n } catch {\n return null\n }\n }\n\n if (!existsSync(configFile)) return null\n\n try {\n const content = readFileSync(configFile, 'utf-8')\n const rawData = JSON.parse(content)\n const parsed = TeamConfigFileSchema.safeParse(rawData)\n if (!parsed.success) {\n debug.warn('TEAM_CONFIG_VALIDATION_FAILED', {\n teamName,\n error: parsed.error.message,\n })\n return null\n }\n const configData = parsed.data\n\n // Map config.json back to Team object\n const team: Team = {\n name: configData.name,\n config: {\n name: configData.name,\n displayMode: (configData.displayMode as TeamDisplayMode) || 'auto',\n maxTeammates: configData.maxTeammates || 10,\n description: configData.description || '',\n },\n members: (configData.members || []).map(m => ({\n id: m.agentId,\n name: m.name,\n agentType: m.agentType,\n status: (m.status as Teammate['status']) || 'idle',\n prompt: m.prompt || '',\n currentTaskId: m.currentTaskId || undefined,\n lastActivity: m.lastActivity || m.joinedAt,\n color: m.color || undefined,\n joinedAt: m.joinedAt,\n backendType: (m.backendType as Teammate['backendType']) || 'in-process',\n tmuxPaneId: m.tmuxPaneId || undefined,\n cwd: m.cwd || process.cwd(),\n subscriptions: m.subscriptions || [],\n worktreePath: m.worktreePath || undefined,\n planModeRequired: m.planModeRequired || false,\n isActive: m.isActive !== false,\n mode: m.mode || undefined,\n parentSessionId: m.parentSessionId || undefined,\n })),\n createdAt: configData.createdAt,\n leadSessionId: configData.leadSessionId || '',\n }\n\n const mailbox = new Mailbox(teamName)\n const taskStore = new TeamTaskStore(teamName)\n mailbox.load()\n taskStore.load()\n\n activeTeams.set(teamName, { team, mailbox, taskStore })\n return team\n } catch {\n return null\n }\n}\n\n/**\n * Resolve display mode based on config and environment.\n *\n * Priority for 'auto':\n * 1. tmux/iTerm2 session detected? \u2192 'tmux'\n * 2. 'in-process' (default \u2014 maximum compatibility)\n */\nexport async function resolveDisplayMode(\n mode: TeamDisplayMode,\n): Promise<'in-process' | 'tmux' | 'aiter'> {\n if (mode === 'in-process') return 'in-process'\n if (mode === 'tmux') return 'tmux'\n if (mode === 'aiter') return 'aiter'\n\n // Auto detection:\n // 1. tmux session detected? \u2192 'tmux'\n // 2. Default: in-process for maximum compatibility\n if (process.env.TMUX || process.env.TERM_PROGRAM === 'iTerm.app') {\n return 'tmux'\n }\n\n return 'in-process'\n}\n\n/**\n * Disband ALL active teams. Called during graceful shutdown to ensure\n * all agent query loops are aborted and resources are cleaned up.\n */\nexport function disbandAllTeams(): void {\n const teamNames = Array.from(activeTeams.keys())\n for (const name of teamNames) {\n try {\n disbandTeam(name)\n } catch (error) {\n debug.warn('TEAM_DISBAND_CLEANUP_FAILED', { teamName: name, error })\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }