@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,172 @@
1
+ import { Box, Text } from "ink";
2
+ import * as React from "react";
3
+ import { z } from "zod";
4
+ import { FallbackToolUseRejectedMessage } from "../../components/FallbackToolUseRejectedMessage.js";
5
+ import { DESCRIPTION, PROMPT } from "./prompt.js";
6
+ import { getDeferredMCPTools, activateMCPTool } from "../../services/mcpClient.js";
7
+ const inputSchema = z.strictObject({
8
+ query: z.string().describe(
9
+ 'Query to find deferred tools. Use "select:<tool_name>" for direct selection, or keywords to search.'
10
+ ),
11
+ max_results: z.number().default(5).describe("Maximum number of results to return (default: 5)")
12
+ });
13
+ function scoreMatch(tool, keywords, requiredKeyword) {
14
+ if (keywords.length === 0) return 0;
15
+ const nameLower = tool.name.toLowerCase();
16
+ const descLower = tool.description.toLowerCase();
17
+ const serverLower = tool.serverName.toLowerCase();
18
+ if (requiredKeyword) {
19
+ const req = requiredKeyword.toLowerCase();
20
+ if (!nameLower.includes(req) && !descLower.includes(req) && !serverLower.includes(req)) {
21
+ return 0;
22
+ }
23
+ }
24
+ let score = 0;
25
+ for (const keyword of keywords) {
26
+ if (nameLower === keyword) {
27
+ score += 10;
28
+ } else if (nameLower.includes(keyword)) {
29
+ score += 5;
30
+ }
31
+ if (descLower.includes(keyword)) {
32
+ score += 2;
33
+ }
34
+ if (serverLower.includes(keyword)) {
35
+ score += 1;
36
+ }
37
+ }
38
+ return score;
39
+ }
40
+ function handleSelectQuery(query, deferred) {
41
+ if (!query.startsWith("select:")) return null;
42
+ const selectPart = query.slice("select:".length).trim();
43
+ if (!selectPart) return null;
44
+ const names = selectPart.split(",").map((n) => n.trim()).filter(Boolean);
45
+ const results = [];
46
+ for (const name of names) {
47
+ const tool = deferred.get(name);
48
+ if (tool) {
49
+ const activated = activateMCPTool(tool.name);
50
+ results.push({
51
+ name: tool.name,
52
+ description: tool.description,
53
+ serverName: tool.serverName,
54
+ activated
55
+ });
56
+ }
57
+ }
58
+ return results;
59
+ }
60
+ const MCPSearchTool = {
61
+ name: "ToolSearch",
62
+ userFacingName: () => "Tool Search",
63
+ description: async () => DESCRIPTION,
64
+ inputSchema,
65
+ async isEnabled() {
66
+ const deferred = getDeferredMCPTools();
67
+ return deferred.size > 0;
68
+ },
69
+ isReadOnly: () => true,
70
+ isConcurrencySafe: () => true,
71
+ needsPermissions: () => false,
72
+ prompt: async () => PROMPT,
73
+ async *call(input) {
74
+ const { query, max_results = 5 } = input;
75
+ const deferred = getDeferredMCPTools();
76
+ const selectResults = handleSelectQuery(query, deferred);
77
+ if (selectResults !== null) {
78
+ const output2 = {
79
+ query,
80
+ results: selectResults,
81
+ totalDeferred: deferred.size
82
+ };
83
+ yield {
84
+ type: "result",
85
+ resultForAssistant: MCPSearchTool.renderResultForAssistant(output2),
86
+ data: output2
87
+ };
88
+ return;
89
+ }
90
+ let searchQuery = query;
91
+ let requiredKeyword;
92
+ if (searchQuery.startsWith("+")) {
93
+ const parts = searchQuery.slice(1).trim().split(/\s+/);
94
+ requiredKeyword = parts[0];
95
+ searchQuery = parts.slice(1).join(" ");
96
+ }
97
+ const keywords = searchQuery.toLowerCase().split(/\s+/).filter((k) => k.length > 0);
98
+ if (requiredKeyword && keywords.length === 0) {
99
+ keywords.push(requiredKeyword.toLowerCase());
100
+ }
101
+ const scored = [];
102
+ for (const [, tool] of deferred) {
103
+ const score = scoreMatch(tool, keywords, requiredKeyword);
104
+ if (score > 0) {
105
+ scored.push({ tool, score });
106
+ }
107
+ }
108
+ scored.sort((a, b) => b.score - a.score);
109
+ const topResults = scored.slice(0, max_results);
110
+ const results = [];
111
+ for (const { tool } of topResults) {
112
+ const activated = activateMCPTool(tool.name);
113
+ results.push({
114
+ name: tool.name,
115
+ description: tool.description,
116
+ serverName: tool.serverName,
117
+ activated
118
+ });
119
+ }
120
+ const output = {
121
+ query,
122
+ results,
123
+ totalDeferred: deferred.size
124
+ };
125
+ yield {
126
+ type: "result",
127
+ resultForAssistant: MCPSearchTool.renderResultForAssistant(output),
128
+ data: output
129
+ };
130
+ },
131
+ renderToolUseMessage(input) {
132
+ return `query: "${input.query}"`;
133
+ },
134
+ renderToolUseRejectedMessage() {
135
+ return /* @__PURE__ */ React.createElement(FallbackToolUseRejectedMessage, null);
136
+ },
137
+ renderToolResultMessage(output) {
138
+ if (!output) {
139
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0No results"));
140
+ }
141
+ const { results, totalDeferred } = output;
142
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0Found ", /* @__PURE__ */ React.createElement(Text, { bold: true }, results.length), " ", "tool", results.length !== 1 ? "s" : "", " (", totalDeferred, " deferred)"));
143
+ },
144
+ renderResultForAssistant(output) {
145
+ const { results, totalDeferred } = output;
146
+ if (results.length === 0) {
147
+ return `No tools found matching "${output.query}". There are ${totalDeferred} deferred tools available. Try a different search query.`;
148
+ }
149
+ const lines = [
150
+ `Found ${results.length} tool${results.length !== 1 ? "s" : ""} matching "${output.query}" (${totalDeferred} total deferred):`,
151
+ ""
152
+ ];
153
+ for (const result of results) {
154
+ const status = result.activated ? "[activated]" : "[already active]";
155
+ lines.push(`${status} ${result.name} (${result.serverName})`);
156
+ if (result.description) {
157
+ lines.push(` ${result.description}`);
158
+ }
159
+ lines.push("");
160
+ }
161
+ if (results.some((r) => r.activated)) {
162
+ lines.push(
163
+ "These tools are now loaded and available. Call them directly in your next response \u2014 do NOT call ToolSearch again for these tools."
164
+ );
165
+ }
166
+ return lines.join("\n");
167
+ }
168
+ };
169
+ export {
170
+ MCPSearchTool
171
+ };
172
+ //# sourceMappingURL=MCPSearchTool.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/tools/MCPSearchTool/MCPSearchTool.tsx"],
4
+ "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { type Tool } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getDeferredMCPTools, activateMCPTool } from '@services/mcpClient'\n\nconst inputSchema = z.strictObject({\n query: z\n .string()\n .describe(\n 'Query to find deferred tools. Use \"select:<tool_name>\" for direct selection, or keywords to search.',\n ),\n max_results: z\n .number()\n .default(5)\n .describe('Maximum number of results to return (default: 5)'),\n})\n\ntype Input = z.infer<typeof inputSchema>\n\ninterface SearchResult {\n name: string\n description: string\n serverName: string\n activated: boolean\n}\n\ntype Output = {\n query: string\n results: SearchResult[]\n totalDeferred: number\n}\n\n/**\n * Score a deferred tool against a search query using keyword matching.\n * Returns 0 for no match, higher scores for better matches.\n */\nfunction scoreMatch(\n tool: { name: string; description: string; serverName: string },\n keywords: string[],\n requiredKeyword?: string,\n): number {\n if (keywords.length === 0) return 0\n\n const nameLower = tool.name.toLowerCase()\n const descLower = tool.description.toLowerCase()\n const serverLower = tool.serverName.toLowerCase()\n\n // If a required keyword is set, the tool must match it\n if (requiredKeyword) {\n const req = requiredKeyword.toLowerCase()\n if (\n !nameLower.includes(req) &&\n !descLower.includes(req) &&\n !serverLower.includes(req)\n ) {\n return 0\n }\n }\n\n let score = 0\n for (const keyword of keywords) {\n // Exact name match is strongest signal\n if (nameLower === keyword) {\n score += 10\n } else if (nameLower.includes(keyword)) {\n score += 5\n }\n\n if (descLower.includes(keyword)) {\n score += 2\n }\n\n if (serverLower.includes(keyword)) {\n score += 1\n }\n }\n\n return score\n}\n\n/**\n * Handle \"select:tool_name\" or \"select:tool1,tool2\" direct selection.\n * Returns matched tools from deferred registry, or null if not a select query.\n */\nfunction handleSelectQuery(\n query: string,\n deferred: Map<\n string,\n { name: string; description: string; serverName: string }\n >,\n): SearchResult[] | null {\n if (!query.startsWith('select:')) return null\n\n const selectPart = query.slice('select:'.length).trim()\n if (!selectPart) return null\n\n const names = selectPart\n .split(',')\n .map(n => n.trim())\n .filter(Boolean)\n const results: SearchResult[] = []\n\n for (const name of names) {\n const tool = deferred.get(name)\n if (tool) {\n const activated = activateMCPTool(tool.name)\n results.push({\n name: tool.name,\n description: tool.description,\n serverName: tool.serverName,\n activated,\n })\n }\n }\n\n return results\n}\n\n// CC-aligned name: ToolSearch (was MCPSearch)\nexport const MCPSearchTool = {\n name: 'ToolSearch',\n userFacingName: () => 'Tool Search',\n description: async () => DESCRIPTION,\n inputSchema,\n async isEnabled() {\n const deferred = getDeferredMCPTools()\n return deferred.size > 0\n },\n isReadOnly: () => true,\n isConcurrencySafe: () => true,\n needsPermissions: () => false,\n prompt: async () => PROMPT,\n\n async *call(input: Input) {\n const { query, max_results = 5 } = input\n const deferred = getDeferredMCPTools()\n\n // Mode 1: Direct selection via \"select:tool_name\"\n const selectResults = handleSelectQuery(query, deferred)\n if (selectResults !== null) {\n const output: Output = {\n query,\n results: selectResults,\n totalDeferred: deferred.size,\n }\n yield {\n type: 'result' as const,\n resultForAssistant: MCPSearchTool.renderResultForAssistant(output),\n data: output,\n }\n return\n }\n\n // Mode 2/3: Keyword search (with optional +required prefix)\n let searchQuery = query\n let requiredKeyword: string | undefined\n if (searchQuery.startsWith('+')) {\n const parts = searchQuery.slice(1).trim().split(/\\s+/)\n requiredKeyword = parts[0]\n searchQuery = parts.slice(1).join(' ')\n }\n\n const keywords = searchQuery\n .toLowerCase()\n .split(/\\s+/)\n .filter(k => k.length > 0)\n // Include required keyword in scoring keywords if there are additional terms\n if (requiredKeyword && keywords.length === 0) {\n keywords.push(requiredKeyword.toLowerCase())\n }\n\n // Score and rank all deferred tools\n const scored: Array<{\n tool: { name: string; description: string; serverName: string }\n score: number\n }> = []\n\n for (const [, tool] of deferred) {\n const score = scoreMatch(tool, keywords, requiredKeyword)\n if (score > 0) {\n scored.push({ tool, score })\n }\n }\n\n // Sort by score descending\n scored.sort((a, b) => b.score - a.score)\n\n // Take top N results (CC default: 5)\n const topResults = scored.slice(0, max_results)\n\n // Activate all matched tools so they become available\n const results: SearchResult[] = []\n for (const { tool } of topResults) {\n const activated = activateMCPTool(tool.name)\n results.push({\n name: tool.name,\n description: tool.description,\n serverName: tool.serverName,\n activated,\n })\n }\n\n const output: Output = {\n query,\n results,\n totalDeferred: deferred.size,\n }\n\n yield {\n type: 'result' as const,\n resultForAssistant: MCPSearchTool.renderResultForAssistant(output),\n data: output,\n }\n },\n\n renderToolUseMessage(input: Input) {\n return `query: \"${input.query}\"`\n },\n\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n\n renderToolResultMessage(output: Output) {\n if (!output) {\n return (\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;&#x23BF; &nbsp;No results</Text>\n </Box>\n )\n }\n\n const { results, totalDeferred } = output\n return (\n <Box flexDirection=\"row\">\n <Text>\n &nbsp;&nbsp;&#x23BF; &nbsp;Found <Text bold>{results.length}</Text>{' '}\n tool\n {results.length !== 1 ? 's' : ''} ({totalDeferred} deferred)\n </Text>\n </Box>\n )\n },\n\n renderResultForAssistant(output: Output): string {\n const { results, totalDeferred } = output\n\n if (results.length === 0) {\n return `No tools found matching \"${output.query}\". There are ${totalDeferred} deferred tools available. Try a different search query.`\n }\n\n const lines = [\n `Found ${results.length} tool${results.length !== 1 ? 's' : ''} matching \"${output.query}\" (${totalDeferred} total deferred):`,\n '',\n ]\n\n for (const result of results) {\n const status = result.activated ? '[activated]' : '[already active]'\n lines.push(`${status} ${result.name} (${result.serverName})`)\n if (result.description) {\n lines.push(` ${result.description}`)\n }\n lines.push('')\n }\n\n if (results.some(r => r.activated)) {\n lines.push(\n 'These tools are now loaded and available. Call them directly in your next response \u2014 do NOT call ToolSearch again for these tools.',\n )\n }\n\n return lines.join('\\n')\n },\n} satisfies Tool\n"],
5
+ "mappings": "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",
6
+ "names": ["output"]
7
+ }
@@ -0,0 +1,77 @@
1
+ const DESCRIPTION = "Search for or select deferred tools to make them available for use.";
2
+ const PROMPT = `Search for or select deferred tools to make them available for use.
3
+
4
+ **MANDATORY PREREQUISITE - THIS IS A HARD REQUIREMENT**
5
+
6
+ You MUST use this tool to load deferred tools BEFORE calling them directly.
7
+
8
+ This is a BLOCKING REQUIREMENT \u2014 deferred tools are NOT available until you load them using this tool. Look for <available-deferred-tools> messages in the conversation for the list of tools you can discover. Both query modes (keyword search and direct selection) load the returned tools \u2014 once a tool appears in the results, it is immediately available to call.
9
+
10
+ **Why this is non-negotiable:**
11
+ - Deferred tools are not loaded until discovered via this tool
12
+ - Calling a deferred tool without first loading it will fail
13
+
14
+ **Query modes:**
15
+
16
+ 1. **Keyword search** - Use keywords when you're unsure which tool to use or need to discover multiple tools at once:
17
+ - "list directory" - find tools for listing directories
18
+ - "notebook jupyter" - find notebook editing tools
19
+ - "slack message" - find slack messaging tools
20
+ - Returns up to 5 matching tools ranked by relevance
21
+ - All returned tools are immediately available to call \u2014 no further selection step needed
22
+
23
+ 2. **Direct selection** - Use \`select:<tool_name>\` when you know the exact tool name:
24
+ - "select:mcp__slack__read_channel"
25
+ - "select:NotebookEdit"
26
+ - "select:Read,Edit,Grep" - load multiple tools at once with comma separation
27
+ - Returns the named tool(s) if they exist
28
+
29
+ **IMPORTANT:** Both modes load tools equally. Do NOT follow up a keyword search with \`select:\` calls for tools already returned \u2014 they are already loaded.
30
+
31
+ 3. **Required keyword** - Prefix with \`+\` to require a match:
32
+ - "+linear create issue" - only tools from "linear", ranked by "create"/"issue"
33
+ - "+slack send" - only "slack" tools, ranked by "send"
34
+ - Useful when you know the service name but not the exact tool
35
+
36
+ **CORRECT Usage Patterns:**
37
+
38
+ <example>
39
+ User: I need to work with slack somehow
40
+ Assistant: Let me search for slack tools.
41
+ [Calls ToolSearch with query: "slack"]
42
+ Assistant: Found several options including mcp__slack__read_channel.
43
+ [Calls mcp__slack__read_channel directly \u2014 it was loaded by the keyword search]
44
+ </example>
45
+
46
+ <example>
47
+ User: Edit the Jupyter notebook
48
+ Assistant: Let me load the notebook editing tool.
49
+ [Calls ToolSearch with query: "select:NotebookEdit"]
50
+ [Calls NotebookEdit]
51
+ </example>
52
+
53
+ <example>
54
+ User: List files in the src directory
55
+ Assistant: I can see mcp__filesystem__list_directory in the available tools. Let me select it.
56
+ [Calls ToolSearch with query: "select:mcp__filesystem__list_directory"]
57
+ [Calls the tool]
58
+ </example>
59
+
60
+ **INCORRECT Usage Patterns - NEVER DO THESE:**
61
+
62
+ <bad-example>
63
+ User: Read my slack messages
64
+ Assistant: [Directly calls mcp__slack__read_channel without loading it first]
65
+ WRONG - You must load the tool FIRST using this tool
66
+ </bad-example>
67
+
68
+ <bad-example>
69
+ Assistant: [Calls ToolSearch with query: "slack", gets back mcp__slack__read_channel]
70
+ Assistant: [Calls ToolSearch with query: "select:mcp__slack__read_channel"]
71
+ WRONG - The keyword search already loaded the tool. The select call is redundant.
72
+ </bad-example>`;
73
+ export {
74
+ DESCRIPTION,
75
+ PROMPT
76
+ };
77
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/tools/MCPSearchTool/prompt.ts"],
4
+ "sourcesContent": ["export const DESCRIPTION =\n 'Search for or select deferred tools to make them available for use.'\n\nexport const PROMPT = `Search for or select deferred tools to make them available for use.\n\n**MANDATORY PREREQUISITE - THIS IS A HARD REQUIREMENT**\n\nYou MUST use this tool to load deferred tools BEFORE calling them directly.\n\nThis is a BLOCKING REQUIREMENT \u2014 deferred tools are NOT available until you load them using this tool. Look for <available-deferred-tools> messages in the conversation for the list of tools you can discover. Both query modes (keyword search and direct selection) load the returned tools \u2014 once a tool appears in the results, it is immediately available to call.\n\n**Why this is non-negotiable:**\n- Deferred tools are not loaded until discovered via this tool\n- Calling a deferred tool without first loading it will fail\n\n**Query modes:**\n\n1. **Keyword search** - Use keywords when you're unsure which tool to use or need to discover multiple tools at once:\n - \"list directory\" - find tools for listing directories\n - \"notebook jupyter\" - find notebook editing tools\n - \"slack message\" - find slack messaging tools\n - Returns up to 5 matching tools ranked by relevance\n - All returned tools are immediately available to call \u2014 no further selection step needed\n\n2. **Direct selection** - Use \\`select:<tool_name>\\` when you know the exact tool name:\n - \"select:mcp__slack__read_channel\"\n - \"select:NotebookEdit\"\n - \"select:Read,Edit,Grep\" - load multiple tools at once with comma separation\n - Returns the named tool(s) if they exist\n\n**IMPORTANT:** Both modes load tools equally. Do NOT follow up a keyword search with \\`select:\\` calls for tools already returned \u2014 they are already loaded.\n\n3. **Required keyword** - Prefix with \\`+\\` to require a match:\n - \"+linear create issue\" - only tools from \"linear\", ranked by \"create\"/\"issue\"\n - \"+slack send\" - only \"slack\" tools, ranked by \"send\"\n - Useful when you know the service name but not the exact tool\n\n**CORRECT Usage Patterns:**\n\n<example>\nUser: I need to work with slack somehow\nAssistant: Let me search for slack tools.\n[Calls ToolSearch with query: \"slack\"]\nAssistant: Found several options including mcp__slack__read_channel.\n[Calls mcp__slack__read_channel directly \u2014 it was loaded by the keyword search]\n</example>\n\n<example>\nUser: Edit the Jupyter notebook\nAssistant: Let me load the notebook editing tool.\n[Calls ToolSearch with query: \"select:NotebookEdit\"]\n[Calls NotebookEdit]\n</example>\n\n<example>\nUser: List files in the src directory\nAssistant: I can see mcp__filesystem__list_directory in the available tools. Let me select it.\n[Calls ToolSearch with query: \"select:mcp__filesystem__list_directory\"]\n[Calls the tool]\n</example>\n\n**INCORRECT Usage Patterns - NEVER DO THESE:**\n\n<bad-example>\nUser: Read my slack messages\nAssistant: [Directly calls mcp__slack__read_channel without loading it first]\nWRONG - You must load the tool FIRST using this tool\n</bad-example>\n\n<bad-example>\nAssistant: [Calls ToolSearch with query: \"slack\", gets back mcp__slack__read_channel]\nAssistant: [Calls ToolSearch with query: \"select:mcp__slack__read_channel\"]\nWRONG - The keyword search already loaded the tool. The select call is redundant.\n</bad-example>`\n"],
5
+ "mappings": "AAAO,MAAM,cACX;AAEK,MAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
6
+ "names": []
7
+ }
@@ -1,11 +1,8 @@
1
- import { NotebookEditTool } from "../NotebookEditTool/NotebookEditTool.js";
2
- import { FileReadTool } from "../FileReadTool/FileReadTool.js";
3
- import { FileEditTool } from "../FileEditTool/FileEditTool.js";
4
- const DESCRIPTION = `This is a tool for making multiple edits to a single file in one operation. It is built on top of the ${FileEditTool.name} tool and allows you to perform multiple find-and-replace operations efficiently. Prefer this tool over the ${FileEditTool.name} tool when you need to make multiple edits to the same file.
1
+ const DESCRIPTION = `This is a tool for making multiple edits to a single file in one operation. It is built on top of the Edit tool and allows you to perform multiple find-and-replace operations efficiently. Prefer this tool over the Edit tool when you need to make multiple edits to the same file.
5
2
 
6
3
  Before using this tool:
7
4
 
8
- 1. Use the ${FileReadTool.name} tool to understand the file's contents and context
5
+ 1. Use the Read tool to understand the file's contents and context
9
6
  2. Verify the directory path is correct
10
7
 
11
8
  To make multiple file edits, provide the following:
@@ -20,10 +17,10 @@ IMPORTANT:
20
17
  - Each edit operates on the result of the previous edit
21
18
  - All edits must be valid for the operation to succeed - if any edit fails, none will be applied
22
19
  - This tool is ideal when you need to make several changes to different parts of the same file
23
- - For Jupyter notebooks (.ipynb files), use the ${NotebookEditTool.name} instead
20
+ - For Jupyter notebooks (.ipynb files), use the NotebookEdit instead
24
21
 
25
22
  CRITICAL REQUIREMENTS:
26
- 1. All edits follow the same requirements as the single ${FileEditTool.name} tool
23
+ 1. All edits follow the same requirements as the single Edit tool
27
24
  2. The edits are atomic - either all succeed or none are applied
28
25
  3. Plan your edits carefully to avoid conflicts between sequential operations
29
26
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/MultiEditTool/prompt.ts"],
4
- "sourcesContent": ["import { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\nimport { FileReadTool } from '@tools/FileReadTool/FileReadTool'\nimport { FileEditTool } from '@tools/FileEditTool/FileEditTool'\n\nexport const DESCRIPTION = `This is a tool for making multiple edits to a single file in one operation. It is built on top of the ${FileEditTool.name} tool and allows you to perform multiple find-and-replace operations efficiently. Prefer this tool over the ${FileEditTool.name} tool when you need to make multiple edits to the same file.\n\nBefore using this tool:\n\n1. Use the ${FileReadTool.name} tool to understand the file's contents and context\n2. Verify the directory path is correct\n\nTo make multiple file edits, provide the following:\n1. file_path: The absolute path to the file to modify (must be absolute, not relative)\n2. edits: An array of edit operations to perform, where each edit contains:\n - old_string: The text to replace (must match the file contents exactly, including all whitespace and indentation)\n - new_string: The edited text to replace the old_string\n - replace_all: Replace all occurences of old_string. This parameter is optional and defaults to false.\n\nIMPORTANT:\n- All edits are applied in sequence, in the order they are provided\n- Each edit operates on the result of the previous edit\n- All edits must be valid for the operation to succeed - if any edit fails, none will be applied\n- This tool is ideal when you need to make several changes to different parts of the same file\n- For Jupyter notebooks (.ipynb files), use the ${NotebookEditTool.name} instead\n\nCRITICAL REQUIREMENTS:\n1. All edits follow the same requirements as the single ${FileEditTool.name} tool\n2. The edits are atomic - either all succeed or none are applied\n3. Plan your edits carefully to avoid conflicts between sequential operations\n\nWARNING:\n- The tool will fail if edits.old_string doesn't match the file contents exactly (including whitespace)\n- The tool will fail if edits.old_string and edits.new_string are the same\n- Since edits are applied in sequence, ensure that earlier edits don't affect the text that later edits are trying to find\n\nWhen making edits:\n- Ensure all edits result in idiomatic, correct code\n- Do not leave the code in a broken state\n- Always use absolute file paths (starting with /)\n- Use replace_all for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance.\n\nIf you want to create a new file, use:\n- A new file path, including dir name if needed\n- First edit: empty old_string and the new file's contents as new_string\n- Subsequent edits: normal edit operations on the created content`\n\nexport const PROMPT = DESCRIPTION\n"],
5
- "mappings": "AAAA,SAAS,wBAAwB;AACjC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAEtB,MAAM,cAAc,yGAAyG,aAAa,IAAI,+GAA+G,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA,aAIxQ,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kDAeoB,iBAAiB,IAAI;AAAA;AAAA;AAAA,0DAGb,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBpE,MAAM,SAAS;",
4
+ "sourcesContent": ["export const DESCRIPTION = `This is a tool for making multiple edits to a single file in one operation. It is built on top of the Edit tool and allows you to perform multiple find-and-replace operations efficiently. Prefer this tool over the Edit tool when you need to make multiple edits to the same file.\n\nBefore using this tool:\n\n1. Use the Read tool to understand the file's contents and context\n2. Verify the directory path is correct\n\nTo make multiple file edits, provide the following:\n1. file_path: The absolute path to the file to modify (must be absolute, not relative)\n2. edits: An array of edit operations to perform, where each edit contains:\n - old_string: The text to replace (must match the file contents exactly, including all whitespace and indentation)\n - new_string: The edited text to replace the old_string\n - replace_all: Replace all occurences of old_string. This parameter is optional and defaults to false.\n\nIMPORTANT:\n- All edits are applied in sequence, in the order they are provided\n- Each edit operates on the result of the previous edit\n- All edits must be valid for the operation to succeed - if any edit fails, none will be applied\n- This tool is ideal when you need to make several changes to different parts of the same file\n- For Jupyter notebooks (.ipynb files), use the NotebookEdit instead\n\nCRITICAL REQUIREMENTS:\n1. All edits follow the same requirements as the single Edit tool\n2. The edits are atomic - either all succeed or none are applied\n3. Plan your edits carefully to avoid conflicts between sequential operations\n\nWARNING:\n- The tool will fail if edits.old_string doesn't match the file contents exactly (including whitespace)\n- The tool will fail if edits.old_string and edits.new_string are the same\n- Since edits are applied in sequence, ensure that earlier edits don't affect the text that later edits are trying to find\n\nWhen making edits:\n- Ensure all edits result in idiomatic, correct code\n- Do not leave the code in a broken state\n- Always use absolute file paths (starting with /)\n- Use replace_all for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance.\n\nIf you want to create a new file, use:\n- A new file path, including dir name if needed\n- First edit: empty old_string and the new file's contents as new_string\n- Subsequent edits: normal edit operations on the created content`\n\nexport const PROMPT = DESCRIPTION\n"],
5
+ "mappings": "AAAO,MAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CpB,MAAM,SAAS;",
6
6
  "names": []
7
7
  }
@@ -45,15 +45,19 @@ const EnterPlanModeTool = {
45
45
  renderResultForAssistant(output) {
46
46
  return `${output.message}
47
47
 
48
- In plan mode, you should:
49
- 1. Thoroughly explore the codebase to understand existing patterns
50
- 2. Identify similar features and architectural approaches
51
- 3. Consider multiple approaches and their trade-offs
52
- 4. Use AskUserQuestion if you need to clarify the approach
53
- 5. Design a concrete implementation strategy
54
- 6. When ready, use ExitPlanMode to present your plan for approval
48
+ Plan mode is active. You MUST NOT make edits or changes except to the plan file. Follow this 5-phase workflow:
55
49
 
56
- Remember: DO NOT write or edit any files yet. This is a read-only exploration and planning phase.`;
50
+ **Phase 1: Initial Understanding** \u2014 Read code, ask clarifying questions, search codebase, identify reusable patterns. Launch explore-type subagents in parallel if needed.
51
+
52
+ **Phase 2: Design** \u2014 Architect an implementation strategy based on exploration findings and user intent.
53
+
54
+ **Phase 3: Review** \u2014 Examine critical files identified in Phase 2. Verify alignment between proposed approach and original requirements. Use AskUserQuestion to resolve ambiguities.
55
+
56
+ **Phase 4: Final Plan** \u2014 Write your plan to the plan file with: context (problem being solved), critical file paths, references to existing utilities, and verification procedures.
57
+
58
+ **Phase 5: Exit** \u2014 Call ExitPlanMode to present your plan for user approval.
59
+
60
+ Remember: All actions must be read-only until user approves. Only the plan file may be written.`;
57
61
  },
58
62
  async *call(_input, context) {
59
63
  if (context?.agentId) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/PlanModeTool/EnterPlanModeTool.tsx"],
4
- "sourcesContent": ["/**\n * Enter Plan Mode Tool\n *\n * Requests permission to enter plan mode for complex tasks.\n */\n\nimport { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Tool } from '@tool'\nimport { enterPlanMode, isPlanModeEnabled } from '@utils/plan/planMode'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { ENTER_DESCRIPTION, ENTER_PROMPT, ENTER_TOOL_NAME } from './prompt'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\nconst inputSchema = z.strictObject({})\n\ntype Output = {\n message: string\n}\n\nexport const EnterPlanModeTool = {\n name: ENTER_TOOL_NAME,\n async description() {\n return ENTER_DESCRIPTION\n },\n userFacingName() {\n return ''\n },\n inputSchema,\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return true\n },\n requiresUserInteraction() {\n return true\n },\n async prompt() {\n return ENTER_PROMPT\n },\n renderToolUseMessage() {\n return ''\n },\n renderToolUseRejectedMessage() {\n return (\n <Box flexDirection=\"row\" marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>\n User declined to enter plan mode\n </Text>\n </Box>\n )\n },\n renderToolResultMessage(_output: Output) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box flexDirection=\"row\">\n <Text color=\"cyan\">\u25CF</Text>\n <Text> Entered plan mode</Text>\n </Box>\n <Box paddingLeft={2}>\n <Text color={SEMANTIC_COLORS.dim}>\n Minto is now exploring and designing an implementation approach.\n </Text>\n </Box>\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n return `${output.message}\n\nIn plan mode, you should:\n1. Thoroughly explore the codebase to understand existing patterns\n2. Identify similar features and architectural approaches\n3. Consider multiple approaches and their trade-offs\n4. Use AskUserQuestion if you need to clarify the approach\n5. Design a concrete implementation strategy\n6. When ready, use ExitPlanMode to present your plan for approval\n\nRemember: DO NOT write or edit any files yet. This is a read-only exploration and planning phase.`\n },\n async *call(_input: z.infer<typeof inputSchema>, context: any) {\n if (context?.agentId) {\n throw new Error('EnterPlanMode tool cannot be used in agent contexts')\n }\n\n const wasAlreadyInPlanMode = isPlanModeEnabled(context)\n const { planFilePath } = enterPlanMode(context)\n\n if (wasAlreadyInPlanMode) {\n emitReminderEvent('plan:mode_reentry', { planPath: planFilePath })\n }\n emitReminderEvent('plan:file_reference', { planPath: planFilePath })\n\n const output: Output = {\n message:\n 'Entered plan mode. You should now focus on exploring the codebase and designing an implementation approach.',\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n },\n} satisfies Tool\n"],
5
- "mappings": "AAMA,SAAS,KAAK,YAAY;AAC1B,OAAO,WAAW;AAClB,SAAS,SAAS;AAElB,SAAS,eAAe,yBAAyB;AACjD,SAAS,yBAAyB;AAClC,SAAS,mBAAmB,cAAc,uBAAuB;AACjE,SAAS,uBAAuB;AAEhC,MAAM,cAAc,EAAE,aAAa,CAAC,CAAC;AAM9B,MAAM,oBAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,MAAM,cAAc;AAClB,WAAO;AAAA,EACT;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA,EACA;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,oBAAoB;AAClB,WAAO;AAAA,EACT;AAAA,EACA,MAAM,YAAY;AAChB,WAAO;AAAA,EACT;AAAA,EACA,mBAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EACA,0BAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS;AACb,WAAO;AAAA,EACT;AAAA,EACA,uBAAuB;AACrB,WAAO;AAAA,EACT;AAAA,EACA,+BAA+B;AAC7B,WACE,oCAAC,OAAI,eAAc,OAAM,WAAW,KAClC,oCAAC,QAAK,OAAO,gBAAgB,OAAK,kCAElC,CACF;AAAA,EAEJ;AAAA,EACA,wBAAwB,SAAiB;AACvC,WACE,oCAAC,OAAI,eAAc,UAAS,WAAW,KACrC,oCAAC,OAAI,eAAc,SACjB,oCAAC,QAAK,OAAM,UAAO,QAAC,GACpB,oCAAC,YAAK,oBAAkB,CAC1B,GACA,oCAAC,OAAI,aAAa,KAChB,oCAAC,QAAK,OAAO,gBAAgB,OAAK,kEAElC,CACF,CACF;AAAA,EAEJ;AAAA,EACA,yBAAyB,QAAgB;AACvC,WAAO,GAAG,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW1B;AAAA,EACA,OAAO,KAAK,QAAqC,SAAc;AAC7D,QAAI,SAAS,SAAS;AACpB,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,UAAM,uBAAuB,kBAAkB,OAAO;AACtD,UAAM,EAAE,aAAa,IAAI,cAAc,OAAO;AAE9C,QAAI,sBAAsB;AACxB,wBAAkB,qBAAqB,EAAE,UAAU,aAAa,CAAC;AAAA,IACnE;AACA,sBAAkB,uBAAuB,EAAE,UAAU,aAAa,CAAC;AAEnE,UAAM,SAAiB;AAAA,MACrB,SACE;AAAA,IACJ;AACA,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,oBAAoB,KAAK,yBAAyB,MAAM;AAAA,IAC1D;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["/**\n * Enter Plan Mode Tool\n *\n * Requests permission to enter plan mode for complex tasks.\n */\n\nimport { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Tool } from '@tool'\nimport { enterPlanMode, isPlanModeEnabled } from '@utils/plan/planMode'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { ENTER_DESCRIPTION, ENTER_PROMPT, ENTER_TOOL_NAME } from './prompt'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\nconst inputSchema = z.strictObject({})\n\ntype Output = {\n message: string\n}\n\nexport const EnterPlanModeTool = {\n name: ENTER_TOOL_NAME,\n async description() {\n return ENTER_DESCRIPTION\n },\n userFacingName() {\n return ''\n },\n inputSchema,\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return true\n },\n requiresUserInteraction() {\n return true\n },\n async prompt() {\n return ENTER_PROMPT\n },\n renderToolUseMessage() {\n return ''\n },\n renderToolUseRejectedMessage() {\n return (\n <Box flexDirection=\"row\" marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>\n User declined to enter plan mode\n </Text>\n </Box>\n )\n },\n renderToolResultMessage(_output: Output) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box flexDirection=\"row\">\n <Text color=\"cyan\">\u25CF</Text>\n <Text> Entered plan mode</Text>\n </Box>\n <Box paddingLeft={2}>\n <Text color={SEMANTIC_COLORS.dim}>\n Minto is now exploring and designing an implementation approach.\n </Text>\n </Box>\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n return `${output.message}\n\nPlan mode is active. You MUST NOT make edits or changes except to the plan file. Follow this 5-phase workflow:\n\n**Phase 1: Initial Understanding** \u2014 Read code, ask clarifying questions, search codebase, identify reusable patterns. Launch explore-type subagents in parallel if needed.\n\n**Phase 2: Design** \u2014 Architect an implementation strategy based on exploration findings and user intent.\n\n**Phase 3: Review** \u2014 Examine critical files identified in Phase 2. Verify alignment between proposed approach and original requirements. Use AskUserQuestion to resolve ambiguities.\n\n**Phase 4: Final Plan** \u2014 Write your plan to the plan file with: context (problem being solved), critical file paths, references to existing utilities, and verification procedures.\n\n**Phase 5: Exit** \u2014 Call ExitPlanMode to present your plan for user approval.\n\nRemember: All actions must be read-only until user approves. Only the plan file may be written.`\n },\n async *call(_input: z.infer<typeof inputSchema>, context: any) {\n if (context?.agentId) {\n throw new Error('EnterPlanMode tool cannot be used in agent contexts')\n }\n\n const wasAlreadyInPlanMode = isPlanModeEnabled(context)\n const { planFilePath } = enterPlanMode(context)\n\n if (wasAlreadyInPlanMode) {\n emitReminderEvent('plan:mode_reentry', { planPath: planFilePath })\n }\n emitReminderEvent('plan:file_reference', { planPath: planFilePath })\n\n const output: Output = {\n message:\n 'Entered plan mode. You should now focus on exploring the codebase and designing an implementation approach.',\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n },\n} satisfies Tool\n"],
5
+ "mappings": "AAMA,SAAS,KAAK,YAAY;AAC1B,OAAO,WAAW;AAClB,SAAS,SAAS;AAElB,SAAS,eAAe,yBAAyB;AACjD,SAAS,yBAAyB;AAClC,SAAS,mBAAmB,cAAc,uBAAuB;AACjE,SAAS,uBAAuB;AAEhC,MAAM,cAAc,EAAE,aAAa,CAAC,CAAC;AAM9B,MAAM,oBAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,MAAM,cAAc;AAClB,WAAO;AAAA,EACT;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA,EACA;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,oBAAoB;AAClB,WAAO;AAAA,EACT;AAAA,EACA,MAAM,YAAY;AAChB,WAAO;AAAA,EACT;AAAA,EACA,mBAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EACA,0BAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS;AACb,WAAO;AAAA,EACT;AAAA,EACA,uBAAuB;AACrB,WAAO;AAAA,EACT;AAAA,EACA,+BAA+B;AAC7B,WACE,oCAAC,OAAI,eAAc,OAAM,WAAW,KAClC,oCAAC,QAAK,OAAO,gBAAgB,OAAK,kCAElC,CACF;AAAA,EAEJ;AAAA,EACA,wBAAwB,SAAiB;AACvC,WACE,oCAAC,OAAI,eAAc,UAAS,WAAW,KACrC,oCAAC,OAAI,eAAc,SACjB,oCAAC,QAAK,OAAM,UAAO,QAAC,GACpB,oCAAC,YAAK,oBAAkB,CAC1B,GACA,oCAAC,OAAI,aAAa,KAChB,oCAAC,QAAK,OAAO,gBAAgB,OAAK,kEAElC,CACF,CACF;AAAA,EAEJ;AAAA,EACA,yBAAyB,QAAgB;AACvC,WAAO,GAAG,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAe1B;AAAA,EACA,OAAO,KAAK,QAAqC,SAAc;AAC7D,QAAI,SAAS,SAAS;AACpB,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,UAAM,uBAAuB,kBAAkB,OAAO;AACtD,UAAM,EAAE,aAAa,IAAI,cAAc,OAAO;AAE9C,QAAI,sBAAsB;AACxB,wBAAkB,qBAAqB,EAAE,UAAU,aAAa,CAAC;AAAA,IACnE;AACA,sBAAkB,uBAAuB,EAAE,UAAU,aAAa,CAAC;AAEnE,UAAM,SAAiB;AAAA,MACrB,SACE;AAAA,IACJ;AACA,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,oBAAoB,KAAK,yBAAyB,MAAM;AAAA,IAC1D;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -47,7 +47,18 @@ const ExitPlanModeTool = {
47
47
  renderToolUseRejectedMessage(_input, options = {}) {
48
48
  const conversationKey = typeof options.conversationKey === "string" && options.conversationKey.trim() ? options.conversationKey.trim() : void 0;
49
49
  const plan = getExitPlanModePlanText(conversationKey);
50
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1, width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, "User rejected the plan:"), /* @__PURE__ */ React.createElement(
50
+ const hasFeedback = typeof options.feedbackText === "string" && options.feedbackText.trim();
51
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1, width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, hasFeedback ? "User rejected the plan with feedback:" : "User rejected the plan:"), hasFeedback ? /* @__PURE__ */ React.createElement(
52
+ Box,
53
+ {
54
+ borderStyle: "round",
55
+ borderColor: "yellow",
56
+ borderDimColor: true,
57
+ paddingX: 1,
58
+ marginY: 1
59
+ },
60
+ /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, options.feedbackText)
61
+ ) : null, /* @__PURE__ */ React.createElement(
51
62
  Box,
52
63
  {
53
64
  borderStyle: "round",
@@ -63,6 +74,9 @@ const ExitPlanModeTool = {
63
74
  if (!output) {
64
75
  return /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, null, "Plan mode completed"));
65
76
  }
77
+ if (output.pendingApproval) {
78
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1, width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "\u25D0"), /* @__PURE__ */ React.createElement(Text, null, " Plan submitted for team-lead approval")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, output.requestId ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Request ID: ", output.requestId) : null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, (output.plan || "").substring(0, 200), "..."))));
79
+ }
66
80
  const planPath = typeof output.filePath === "string" ? output.filePath : null;
67
81
  const plan = output.plan || "No plan found";
68
82
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1, width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: "cyan" }, "\u25CF"), /* @__PURE__ */ React.createElement(Text, null, " User approved the plan")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, planPath ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Plan saved to: ", planPath) : null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, plan.substring(0, 200), "..."))));
@@ -91,6 +105,45 @@ ${output.plan}`;
91
105
  `No plan file found at ${planFilePath}. Please write your plan to this file before calling ExitPlanMode.`
92
106
  );
93
107
  }
108
+ const teamName = process.env.MINTO_TEAM_NAME;
109
+ const planModeRequired = process.env.MINTO_PLAN_MODE_REQUIRED === "1";
110
+ if (teamName && planModeRequired) {
111
+ try {
112
+ const { getTeam } = await import("../../services/agentTeams/teamManager.js");
113
+ const entry = getTeam(teamName);
114
+ if (entry) {
115
+ const agentId = process.env.MINTO_AGENT_ID || context?.agentId || "unknown";
116
+ const agentName = agentId.split("@")[0] || agentId;
117
+ const leadId = `team-lead@${teamName}`;
118
+ const requestId = `plan-${Date.now()}@${agentName}`;
119
+ const approvalRequest = JSON.stringify({
120
+ type: "plan_approval_request",
121
+ requestId,
122
+ agent_id: agentId,
123
+ planContent: content.slice(0, 2e3),
124
+ // Truncate for message
125
+ planFilePath,
126
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
127
+ });
128
+ entry.mailbox.send(agentId, leadId, approvalRequest, {
129
+ summary: `Plan approval request from ${agentName}`
130
+ });
131
+ yield {
132
+ type: "result",
133
+ data: {
134
+ plan: content,
135
+ isAgent: true,
136
+ filePath: planFilePath,
137
+ pendingApproval: true,
138
+ requestId
139
+ },
140
+ resultForAssistant: `Plan submitted for approval. Request ID: ${requestId}. Wait for team-lead to approve or reject your plan via SendMessage. Do NOT proceed with implementation until approved.`
141
+ };
142
+ return;
143
+ }
144
+ } catch {
145
+ }
146
+ }
94
147
  emitReminderEvent("plan:exited", { planPath: planFilePath });
95
148
  const isAgent = !!context?.agentId;
96
149
  const output = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/PlanModeTool/ExitPlanModeTool.tsx"],
4
- "sourcesContent": ["/**\n * Exit Plan Mode Tool\n *\n * Prompts the user to exit plan mode and start coding.\n */\n\nimport { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Tool } from '@tool'\nimport {\n getPlanConversationKey,\n getPlanFilePath,\n readPlanFile,\n} from '@utils/plan/planMode'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { EXIT_DESCRIPTION, EXIT_PROMPT, EXIT_TOOL_NAME } from './prompt'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\nfunction getExitPlanModePlanText(conversationKey?: string): string {\n const { content } = readPlanFile(undefined, conversationKey)\n return (\n content || 'No plan found. Please write your plan to the plan file first.'\n )\n}\n\nconst inputSchema = z.strictObject({}).passthrough()\n\ntype Output = {\n plan: string\n isAgent: boolean\n filePath?: string\n}\n\nexport const ExitPlanModeTool = {\n name: EXIT_TOOL_NAME,\n async description() {\n return EXIT_DESCRIPTION\n },\n userFacingName() {\n return ''\n },\n inputSchema,\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return true\n },\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return true\n },\n requiresUserInteraction() {\n return true\n },\n async prompt() {\n return EXIT_PROMPT\n },\n renderToolUseMessage() {\n return ''\n },\n renderToolUseRejectedMessage(\n _input: z.infer<typeof inputSchema>,\n options: { conversationKey?: string } = {},\n ) {\n const conversationKey =\n typeof options.conversationKey === 'string' &&\n options.conversationKey.trim()\n ? options.conversationKey.trim()\n : undefined\n\n const plan = getExitPlanModePlanText(conversationKey)\n\n return (\n <Box flexDirection=\"column\" marginTop={1} width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Box flexDirection=\"column\" width=\"100%\">\n <Text color=\"red\">User rejected the plan:</Text>\n <Box\n borderStyle=\"round\"\n borderColor=\"cyan\"\n borderDimColor\n paddingX={1}\n overflow=\"hidden\"\n >\n <Text color={SEMANTIC_COLORS.dim}>{plan}</Text>\n </Box>\n </Box>\n </Box>\n </Box>\n )\n },\n renderToolResultMessage(output: Output) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>Plan mode completed</Text>\n </Box>\n )\n }\n\n const planPath =\n typeof output.filePath === 'string' ? output.filePath : null\n const plan = output.plan || 'No plan found'\n\n return (\n <Box flexDirection=\"column\" marginTop={1} width=\"100%\">\n <Box flexDirection=\"row\">\n <Text color=\"cyan\">\u25CF</Text>\n <Text> User approved the plan</Text>\n </Box>\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Box flexDirection=\"column\">\n {planPath ? (\n <Text color={SEMANTIC_COLORS.dim}>Plan saved to: {planPath}</Text>\n ) : null}\n <Text color={SEMANTIC_COLORS.dim}>{plan.substring(0, 200)}...</Text>\n </Box>\n </Box>\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n if (!output) {\n return 'Plan mode completed'\n }\n\n if (output.isAgent) {\n return 'User has approved the plan. There is nothing else needed from you now. Please respond with \"ok\"'\n }\n\n return `User has approved your plan. You can now start coding. Start with updating your todo list if applicable\n\nYour plan has been saved to: ${output.filePath}\nYou can refer back to it if needed during implementation.\n\n## Approved Plan:\n${output.plan}`\n },\n async *call(input: z.infer<typeof inputSchema>, context: any) {\n const conversationKey = getPlanConversationKey(context)\n const planFilePath = getPlanFilePath(context?.agentId, conversationKey)\n const { content, exists } = readPlanFile(context?.agentId, conversationKey)\n\n if (!exists) {\n throw new Error(\n `No plan file found at ${planFilePath}. Please write your plan to this file before calling ExitPlanMode.`,\n )\n }\n\n emitReminderEvent('plan:exited', { planPath: planFilePath })\n\n const isAgent = !!context?.agentId\n const output: Output = {\n plan: content,\n isAgent,\n filePath: planFilePath,\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n },\n} satisfies Tool\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Exit Plan Mode Tool\n *\n * Prompts the user to exit plan mode and start coding.\n */\n\nimport { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Tool } from '@tool'\nimport {\n getPlanConversationKey,\n getPlanFilePath,\n readPlanFile,\n} from '@utils/plan/planMode'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { EXIT_DESCRIPTION, EXIT_PROMPT, EXIT_TOOL_NAME } from './prompt'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\nfunction getExitPlanModePlanText(conversationKey?: string): string {\n const { content } = readPlanFile(undefined, conversationKey)\n return (\n content || 'No plan found. Please write your plan to the plan file first.'\n )\n}\n\nconst inputSchema = z.strictObject({}).passthrough()\n\ntype Output = {\n plan: string\n isAgent: boolean\n filePath?: string\n pendingApproval?: boolean\n requestId?: string\n}\n\nexport const ExitPlanModeTool = {\n name: EXIT_TOOL_NAME,\n async description() {\n return EXIT_DESCRIPTION\n },\n userFacingName() {\n return ''\n },\n inputSchema,\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return true\n },\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return true\n },\n requiresUserInteraction() {\n return true\n },\n async prompt() {\n return EXIT_PROMPT\n },\n renderToolUseMessage() {\n return ''\n },\n renderToolUseRejectedMessage(\n _input: z.infer<typeof inputSchema>,\n options: { conversationKey?: string; feedbackText?: string } = {},\n ) {\n const conversationKey =\n typeof options.conversationKey === 'string' &&\n options.conversationKey.trim()\n ? options.conversationKey.trim()\n : undefined\n\n const plan = getExitPlanModePlanText(conversationKey)\n const hasFeedback =\n typeof options.feedbackText === 'string' && options.feedbackText.trim()\n\n return (\n <Box flexDirection=\"column\" marginTop={1} width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Box flexDirection=\"column\" width=\"100%\">\n <Text color=\"red\">\n {hasFeedback\n ? 'User rejected the plan with feedback:'\n : 'User rejected the plan:'}\n </Text>\n {hasFeedback ? (\n <Box\n borderStyle=\"round\"\n borderColor=\"yellow\"\n borderDimColor\n paddingX={1}\n marginY={1}\n >\n <Text color=\"yellow\">{options.feedbackText}</Text>\n </Box>\n ) : null}\n <Box\n borderStyle=\"round\"\n borderColor=\"cyan\"\n borderDimColor\n paddingX={1}\n overflow=\"hidden\"\n >\n <Text color={SEMANTIC_COLORS.dim}>{plan}</Text>\n </Box>\n </Box>\n </Box>\n </Box>\n )\n },\n renderToolResultMessage(output: Output) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>Plan mode completed</Text>\n </Box>\n )\n }\n\n // Pending approval case: plan submitted to team lead\n if (output.pendingApproval) {\n return (\n <Box flexDirection=\"column\" marginTop={1} width=\"100%\">\n <Box flexDirection=\"row\">\n <Text color=\"yellow\">\u25D0</Text>\n <Text> Plan submitted for team-lead approval</Text>\n </Box>\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Box flexDirection=\"column\">\n {output.requestId ? (\n <Text color={SEMANTIC_COLORS.dim}>\n Request ID: {output.requestId}\n </Text>\n ) : null}\n <Text color={SEMANTIC_COLORS.dim}>\n {(output.plan || '').substring(0, 200)}...\n </Text>\n </Box>\n </Box>\n </Box>\n )\n }\n\n const planPath =\n typeof output.filePath === 'string' ? output.filePath : null\n const plan = output.plan || 'No plan found'\n\n return (\n <Box flexDirection=\"column\" marginTop={1} width=\"100%\">\n <Box flexDirection=\"row\">\n <Text color=\"cyan\">\u25CF</Text>\n <Text> User approved the plan</Text>\n </Box>\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Box flexDirection=\"column\">\n {planPath ? (\n <Text color={SEMANTIC_COLORS.dim}>Plan saved to: {planPath}</Text>\n ) : null}\n <Text color={SEMANTIC_COLORS.dim}>{plan.substring(0, 200)}...</Text>\n </Box>\n </Box>\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n if (!output) {\n return 'Plan mode completed'\n }\n\n if (output.isAgent) {\n return 'User has approved the plan. There is nothing else needed from you now. Please respond with \"ok\"'\n }\n\n return `User has approved your plan. You can now start coding. Start with updating your todo list if applicable\n\nYour plan has been saved to: ${output.filePath}\nYou can refer back to it if needed during implementation.\n\n## Approved Plan:\n${output.plan}`\n },\n async *call(input: z.infer<typeof inputSchema>, context: any) {\n const conversationKey = getPlanConversationKey(context)\n const planFilePath = getPlanFilePath(context?.agentId, conversationKey)\n const { content, exists } = readPlanFile(context?.agentId, conversationKey)\n\n if (!exists) {\n throw new Error(\n `No plan file found at ${planFilePath}. Please write your plan to this file before calling ExitPlanMode.`,\n )\n }\n\n // Check if in team context with planModeRequired\n const teamName = process.env.MINTO_TEAM_NAME\n const planModeRequired = process.env.MINTO_PLAN_MODE_REQUIRED === '1'\n\n if (teamName && planModeRequired) {\n // Send plan_approval_request to team lead instead of exiting directly\n try {\n const { getTeam } = await import('@services/agentTeams/teamManager')\n const entry = getTeam(teamName)\n if (entry) {\n const agentId =\n process.env.MINTO_AGENT_ID || context?.agentId || 'unknown'\n const agentName = agentId.split('@')[0] || agentId\n const leadId = `team-lead@${teamName}`\n const requestId = `plan-${Date.now()}@${agentName}`\n\n const approvalRequest = JSON.stringify({\n type: 'plan_approval_request',\n requestId,\n agent_id: agentId,\n planContent: content.slice(0, 2000), // Truncate for message\n planFilePath,\n timestamp: new Date().toISOString(),\n })\n\n entry.mailbox.send(agentId, leadId, approvalRequest, {\n summary: `Plan approval request from ${agentName}`,\n })\n\n // Don't actually exit plan mode \u2014 return with pending status\n yield {\n type: 'result',\n data: {\n plan: content,\n isAgent: true,\n filePath: planFilePath,\n pendingApproval: true,\n requestId,\n },\n resultForAssistant: `Plan submitted for approval. Request ID: ${requestId}. Wait for team-lead to approve or reject your plan via SendMessage. Do NOT proceed with implementation until approved.`,\n }\n return\n }\n } catch {\n // Fall through to normal exit if team context unavailable\n }\n }\n\n // Normal exit (non-team or planModeRequired not set)\n emitReminderEvent('plan:exited', { planPath: planFilePath })\n\n const isAgent = !!context?.agentId\n const output: Output = {\n plan: content,\n isAgent,\n filePath: planFilePath,\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n },\n} satisfies Tool\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }