@within-7/minto 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (487) hide show
  1. package/cli.js +155 -37
  2. package/dist/Tool.js +38 -0
  3. package/dist/Tool.js.map +3 -3
  4. package/dist/commands/agents/AgentsCommand.js +52 -26
  5. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  6. package/dist/commands/agents/constants.js +1 -1
  7. package/dist/commands/agents/constants.js.map +1 -1
  8. package/dist/commands/agents/index.js +1 -1
  9. package/dist/commands/bug.js +74 -7
  10. package/dist/commands/bug.js.map +3 -3
  11. package/dist/commands/clear.js +3 -0
  12. package/dist/commands/clear.js.map +2 -2
  13. package/dist/commands/compact.js +37 -0
  14. package/dist/commands/compact.js.map +2 -2
  15. package/dist/commands/context.js +84 -0
  16. package/dist/commands/context.js.map +7 -0
  17. package/dist/commands/ctx_viz.js +18 -10
  18. package/dist/commands/ctx_viz.js.map +2 -2
  19. package/dist/commands/doctor.js +158 -12
  20. package/dist/commands/doctor.js.map +2 -2
  21. package/dist/commands/export.js +156 -0
  22. package/dist/commands/export.js.map +7 -0
  23. package/dist/commands/mcp-interactive.js +21 -12
  24. package/dist/commands/mcp-interactive.js.map +2 -2
  25. package/dist/commands/model.js +6 -5
  26. package/dist/commands/model.js.map +2 -2
  27. package/dist/commands/permissions.js +86 -0
  28. package/dist/commands/permissions.js.map +7 -0
  29. package/dist/commands/quit.js +3 -1
  30. package/dist/commands/quit.js.map +2 -2
  31. package/dist/commands/sandbox.js +104 -0
  32. package/dist/commands/sandbox.js.map +7 -0
  33. package/dist/commands/status.js +58 -0
  34. package/dist/commands/status.js.map +7 -0
  35. package/dist/commands/tasks.js +108 -0
  36. package/dist/commands/tasks.js.map +7 -0
  37. package/dist/commands/todos.js +123 -0
  38. package/dist/commands/todos.js.map +7 -0
  39. package/dist/commands.js +20 -2
  40. package/dist/commands.js.map +2 -2
  41. package/dist/components/AgentThinkingBlock.js +10 -18
  42. package/dist/components/AgentThinkingBlock.js.map +2 -2
  43. package/dist/components/BackgroundTasksPanel.js +78 -29
  44. package/dist/components/BackgroundTasksPanel.js.map +2 -2
  45. package/dist/components/BashStreamingProgress.js +24 -0
  46. package/dist/components/BashStreamingProgress.js.map +7 -0
  47. package/dist/components/CollapsibleHint.js +14 -0
  48. package/dist/components/CollapsibleHint.js.map +7 -0
  49. package/dist/components/FileEditToolUpdatedMessage.js +1 -1
  50. package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
  51. package/dist/components/HotkeyHelpPanel.js +137 -0
  52. package/dist/components/HotkeyHelpPanel.js.map +7 -0
  53. package/dist/components/Logo.js +5 -5
  54. package/dist/components/Logo.js.map +2 -2
  55. package/dist/components/Message.js +23 -7
  56. package/dist/components/Message.js.map +3 -3
  57. package/dist/components/ModelConfig.js +16 -3
  58. package/dist/components/ModelConfig.js.map +2 -2
  59. package/dist/components/ModelListManager.js +3 -3
  60. package/dist/components/ModelListManager.js.map +2 -2
  61. package/dist/components/ModelSelector/ModelSelector.js +1 -1
  62. package/dist/components/Onboarding.js +19 -14
  63. package/dist/components/Onboarding.js.map +2 -2
  64. package/dist/components/ProgressBar.js +74 -0
  65. package/dist/components/ProgressBar.js.map +7 -0
  66. package/dist/components/PromptInput.js +156 -46
  67. package/dist/components/PromptInput.js.map +2 -2
  68. package/dist/components/RequestStatusIndicator.js +194 -0
  69. package/dist/components/RequestStatusIndicator.js.map +7 -0
  70. package/dist/components/Spinner.js +92 -27
  71. package/dist/components/Spinner.js.map +2 -2
  72. package/dist/components/SpinnerSymbol.js +21 -27
  73. package/dist/components/SpinnerSymbol.js.map +2 -2
  74. package/dist/components/StreamingBashOutput.js +9 -8
  75. package/dist/components/StreamingBashOutput.js.map +2 -2
  76. package/dist/components/SubagentBlock.js +1 -1
  77. package/dist/components/SubagentBlock.js.map +1 -1
  78. package/dist/components/SubagentProgress.js +10 -11
  79. package/dist/components/SubagentProgress.js.map +2 -2
  80. package/dist/components/TaskCard.js +16 -13
  81. package/dist/components/TaskCard.js.map +2 -2
  82. package/dist/components/TodoChangeBlock.js +1 -1
  83. package/dist/components/TodoChangeBlock.js.map +2 -2
  84. package/dist/components/TodoPanel.js +120 -29
  85. package/dist/components/TodoPanel.js.map +3 -3
  86. package/dist/components/TokenCounter.js +74 -0
  87. package/dist/components/TokenCounter.js.map +7 -0
  88. package/dist/components/TokenWarning.js +2 -1
  89. package/dist/components/TokenWarning.js.map +2 -2
  90. package/dist/components/TreeConnector.js +25 -0
  91. package/dist/components/TreeConnector.js.map +7 -0
  92. package/dist/components/TurnCompletionIndicator.js +18 -0
  93. package/dist/components/TurnCompletionIndicator.js.map +7 -0
  94. package/dist/components/messages/AssistantTextMessage.js +5 -2
  95. package/dist/components/messages/AssistantTextMessage.js.map +2 -2
  96. package/dist/components/messages/AssistantThinkingMessage.js +18 -3
  97. package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
  98. package/dist/components/messages/AssistantToolUseMessage.js +11 -8
  99. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  100. package/dist/components/messages/GroupRenderer.js +53 -0
  101. package/dist/components/messages/GroupRenderer.js.map +7 -0
  102. package/dist/components/messages/NestedTasksPreview.js +12 -0
  103. package/dist/components/messages/NestedTasksPreview.js.map +7 -0
  104. package/dist/components/messages/ParallelTasksGroupView.js +92 -0
  105. package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
  106. package/dist/components/messages/TaskInModuleView.js +198 -0
  107. package/dist/components/messages/TaskInModuleView.js.map +7 -0
  108. package/dist/components/messages/TaskOutputContent.js +53 -0
  109. package/dist/components/messages/TaskOutputContent.js.map +7 -0
  110. package/dist/components/messages/UserPromptMessage.js +1 -1
  111. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  112. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
  113. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
  114. package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
  115. package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
  116. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
  117. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
  118. package/dist/constants/colors.js +48 -0
  119. package/dist/constants/colors.js.map +2 -2
  120. package/dist/constants/formatRules.js +102 -0
  121. package/dist/constants/formatRules.js.map +7 -0
  122. package/dist/constants/prompts.js +12 -34
  123. package/dist/constants/prompts.js.map +2 -2
  124. package/dist/constants/symbols.js +64 -6
  125. package/dist/constants/symbols.js.map +2 -2
  126. package/dist/constants/timing.js +5 -0
  127. package/dist/constants/timing.js.map +2 -2
  128. package/dist/core/config/defaults.js +84 -0
  129. package/dist/core/config/defaults.js.map +7 -0
  130. package/dist/core/config/index.js +111 -0
  131. package/dist/core/config/index.js.map +7 -0
  132. package/dist/core/config/loader.js +221 -0
  133. package/dist/core/config/loader.js.map +7 -0
  134. package/dist/core/config/migrations.js +128 -0
  135. package/dist/core/config/migrations.js.map +7 -0
  136. package/dist/core/config/schema.js +178 -0
  137. package/dist/core/config/schema.js.map +7 -0
  138. package/dist/core/costTracker.js +138 -0
  139. package/dist/core/costTracker.js.map +7 -0
  140. package/dist/core/index.js +5 -0
  141. package/dist/core/index.js.map +7 -0
  142. package/dist/core/permissions/auditLog.js +204 -0
  143. package/dist/core/permissions/auditLog.js.map +7 -0
  144. package/dist/core/permissions/engine/index.js +3 -0
  145. package/dist/core/permissions/engine/index.js.map +7 -0
  146. package/dist/core/permissions/engine/permissionEngine.js +106 -0
  147. package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
  148. package/dist/core/permissions/engine/types.js +1 -0
  149. package/dist/core/permissions/engine/types.js.map +7 -0
  150. package/dist/core/permissions/index.js +84 -0
  151. package/dist/core/permissions/index.js.map +7 -0
  152. package/dist/core/permissions/ruleEngine.js +259 -0
  153. package/dist/core/permissions/ruleEngine.js.map +7 -0
  154. package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
  155. package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
  156. package/dist/core/permissions/rules/autoEscalationRule.js +291 -0
  157. package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
  158. package/dist/core/permissions/rules/index.js +46 -0
  159. package/dist/core/permissions/rules/index.js.map +7 -0
  160. package/dist/core/permissions/rules/planModeRule.js +55 -0
  161. package/dist/core/permissions/rules/planModeRule.js.map +7 -0
  162. package/dist/core/permissions/rules/projectBoundaryRule.js +168 -0
  163. package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
  164. package/dist/core/permissions/rules/safeModeRule.js +65 -0
  165. package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
  166. package/dist/core/permissions/rules/sensitivePathsRule.js +340 -0
  167. package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
  168. package/dist/core/permissions/types.js +127 -0
  169. package/dist/core/permissions/types.js.map +7 -0
  170. package/dist/core/tools/executor.js +143 -0
  171. package/dist/core/tools/executor.js.map +7 -0
  172. package/dist/core/tools/index.js +15 -0
  173. package/dist/core/tools/index.js.map +7 -0
  174. package/dist/core/tools/registry.js +183 -0
  175. package/dist/core/tools/registry.js.map +7 -0
  176. package/dist/core/tools/types.js +1 -0
  177. package/dist/core/tools/types.js.map +7 -0
  178. package/dist/cost-tracker.js +23 -15
  179. package/dist/cost-tracker.js.map +2 -2
  180. package/dist/entrypoints/cli.js +43 -43
  181. package/dist/entrypoints/cli.js.map +2 -2
  182. package/dist/entrypoints/mcp.js +12 -4
  183. package/dist/entrypoints/mcp.js.map +2 -2
  184. package/dist/history.js +14 -3
  185. package/dist/history.js.map +2 -2
  186. package/dist/hooks/useAgentTranscripts.js +116 -0
  187. package/dist/hooks/useAgentTranscripts.js.map +7 -0
  188. package/dist/hooks/useAnimationSync.js +53 -0
  189. package/dist/hooks/useAnimationSync.js.map +7 -0
  190. package/dist/hooks/useArrowKeyHistory.js +4 -2
  191. package/dist/hooks/useArrowKeyHistory.js.map +2 -2
  192. package/dist/hooks/useCanUseTool.js +3 -1
  193. package/dist/hooks/useCanUseTool.js.map +2 -2
  194. package/dist/hooks/useCancelRequest.js +4 -1
  195. package/dist/hooks/useCancelRequest.js.map +2 -2
  196. package/dist/hooks/useExitOnCtrlCD.js +9 -5
  197. package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
  198. package/dist/hooks/useHookStatus.js +40 -0
  199. package/dist/hooks/useHookStatus.js.map +7 -0
  200. package/dist/hooks/useLogMessages.js +17 -1
  201. package/dist/hooks/useLogMessages.js.map +2 -2
  202. package/dist/hooks/useMessageGroups.js +43 -0
  203. package/dist/hooks/useMessageGroups.js.map +7 -0
  204. package/dist/hooks/useTerminalSize.js +62 -6
  205. package/dist/hooks/useTerminalSize.js.map +2 -2
  206. package/dist/hooks/useUnifiedCompletion.js +69 -0
  207. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  208. package/dist/i18n/index.js +109 -0
  209. package/dist/i18n/index.js.map +7 -0
  210. package/dist/i18n/locales/en.js +347 -0
  211. package/dist/i18n/locales/en.js.map +7 -0
  212. package/dist/i18n/locales/index.js +7 -0
  213. package/dist/i18n/locales/index.js.map +7 -0
  214. package/dist/i18n/locales/zh-CN.js +347 -0
  215. package/dist/i18n/locales/zh-CN.js.map +7 -0
  216. package/dist/i18n/types.js +8 -0
  217. package/dist/i18n/types.js.map +7 -0
  218. package/dist/query.js +175 -17
  219. package/dist/query.js.map +3 -3
  220. package/dist/screens/REPL.js +501 -192
  221. package/dist/screens/REPL.js.map +3 -3
  222. package/dist/services/adapters/chatCompletions.js +3 -1
  223. package/dist/services/adapters/chatCompletions.js.map +2 -2
  224. package/dist/services/adapters/messageNormalizer.js +354 -0
  225. package/dist/services/adapters/messageNormalizer.js.map +7 -0
  226. package/dist/services/adapters/responsesAPI.js +6 -3
  227. package/dist/services/adapters/responsesAPI.js.map +2 -2
  228. package/dist/services/checkpointManager.js +386 -0
  229. package/dist/services/checkpointManager.js.map +7 -0
  230. package/dist/services/claude.js +138 -11
  231. package/dist/services/claude.js.map +3 -3
  232. package/dist/services/compressionService.js +50 -1
  233. package/dist/services/compressionService.js.map +2 -2
  234. package/dist/services/contextMonitor.js +162 -0
  235. package/dist/services/contextMonitor.js.map +7 -0
  236. package/dist/services/customCommands.js +60 -41
  237. package/dist/services/customCommands.js.map +2 -2
  238. package/dist/services/hookExecutor.js +173 -1
  239. package/dist/services/hookExecutor.js.map +2 -2
  240. package/dist/services/intelligentCompactor.js +281 -0
  241. package/dist/services/intelligentCompactor.js.map +7 -0
  242. package/dist/services/lspConfig.js +109 -0
  243. package/dist/services/lspConfig.js.map +7 -0
  244. package/dist/services/mcpClient.js +273 -34
  245. package/dist/services/mcpClient.js.map +2 -2
  246. package/dist/services/modelOrchestrator.js +310 -0
  247. package/dist/services/modelOrchestrator.js.map +7 -0
  248. package/dist/services/openai.js +8 -1
  249. package/dist/services/openai.js.map +2 -2
  250. package/dist/services/outputStyles.js +138 -0
  251. package/dist/services/outputStyles.js.map +7 -0
  252. package/dist/services/plugins/index.js +5 -0
  253. package/dist/services/plugins/index.js.map +7 -0
  254. package/dist/services/plugins/lspServers.js +188 -0
  255. package/dist/services/plugins/lspServers.js.map +7 -0
  256. package/dist/services/plugins/pluginRuntime.js +229 -0
  257. package/dist/services/plugins/pluginRuntime.js.map +7 -0
  258. package/dist/services/plugins/pluginValidation.js +219 -0
  259. package/dist/services/plugins/pluginValidation.js.map +7 -0
  260. package/dist/services/plugins/skillMarketplace.js +556 -0
  261. package/dist/services/plugins/skillMarketplace.js.map +7 -0
  262. package/dist/services/responseStateManager.js +37 -3
  263. package/dist/services/responseStateManager.js.map +2 -2
  264. package/dist/services/sandbox/filesystemBoundary.js +300 -0
  265. package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
  266. package/dist/services/sandbox/index.js +14 -0
  267. package/dist/services/sandbox/index.js.map +7 -0
  268. package/dist/services/sandbox/networkProxy.js +293 -0
  269. package/dist/services/sandbox/networkProxy.js.map +7 -0
  270. package/dist/services/sandbox/sandboxController.js +574 -0
  271. package/dist/services/sandbox/sandboxController.js.map +7 -0
  272. package/dist/services/sandbox/types.js +50 -0
  273. package/dist/services/sandbox/types.js.map +7 -0
  274. package/dist/services/sessionMemory.js +266 -0
  275. package/dist/services/sessionMemory.js.map +7 -0
  276. package/dist/services/taskRouter.js +324 -0
  277. package/dist/services/taskRouter.js.map +7 -0
  278. package/dist/tools/ArchitectTool/ArchitectTool.js +10 -3
  279. package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
  280. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -0
  281. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  282. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +8 -1
  283. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
  284. package/dist/tools/BaseTool.js +72 -0
  285. package/dist/tools/BaseTool.js.map +7 -0
  286. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
  287. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
  288. package/dist/tools/BashTool/BashTool.js +60 -3
  289. package/dist/tools/BashTool/BashTool.js.map +2 -2
  290. package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
  291. package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
  292. package/dist/tools/BashTool/OutputLine.js +54 -0
  293. package/dist/tools/BashTool/OutputLine.js.map +2 -2
  294. package/dist/tools/BashTool/prompt.js +192 -3
  295. package/dist/tools/BashTool/prompt.js.map +2 -2
  296. package/dist/tools/FileEditTool/FileEditTool.js +29 -4
  297. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  298. package/dist/tools/FileReadTool/FileReadTool.js +23 -4
  299. package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
  300. package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
  301. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  302. package/dist/tools/GlobTool/GlobTool.js +14 -3
  303. package/dist/tools/GlobTool/GlobTool.js.map +2 -2
  304. package/dist/tools/GrepTool/GrepTool.js +41 -7
  305. package/dist/tools/GrepTool/GrepTool.js.map +2 -2
  306. package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
  307. package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
  308. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
  309. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
  310. package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
  311. package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
  312. package/dist/tools/LspTool/LspTool.js +664 -0
  313. package/dist/tools/LspTool/LspTool.js.map +7 -0
  314. package/dist/tools/LspTool/prompt.js +27 -0
  315. package/dist/tools/LspTool/prompt.js.map +7 -0
  316. package/dist/tools/MCPTool/MCPTool.js +11 -4
  317. package/dist/tools/MCPTool/MCPTool.js.map +2 -2
  318. package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
  319. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  320. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
  321. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  322. package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
  323. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  324. package/dist/tools/NotebookEditTool/NotebookEditTool.js +5 -1
  325. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  326. package/dist/tools/NotebookReadTool/NotebookReadTool.js +8 -4
  327. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
  328. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +74 -0
  329. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
  330. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +108 -0
  331. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
  332. package/dist/tools/PlanModeTool/prompt.js +94 -0
  333. package/dist/tools/PlanModeTool/prompt.js.map +7 -0
  334. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
  335. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
  336. package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
  337. package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
  338. package/dist/tools/SkillTool/SkillTool.js +14 -3
  339. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  340. package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
  341. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
  342. package/dist/tools/SlashCommandTool/prompt.js +35 -0
  343. package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
  344. package/dist/tools/TaskOutputTool/TaskOutputTool.js +189 -0
  345. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
  346. package/dist/tools/TaskOutputTool/prompt.js +15 -0
  347. package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
  348. package/dist/tools/TaskTool/TaskTool.js +321 -146
  349. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  350. package/dist/tools/TaskTool/prompt.js.map +2 -2
  351. package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -73
  352. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
  353. package/dist/tools/URLFetcherTool/URLFetcherTool.js +7 -1
  354. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
  355. package/dist/tools/URLFetcherTool/cache.js +55 -8
  356. package/dist/tools/URLFetcherTool/cache.js.map +2 -2
  357. package/dist/tools/WebSearchTool/WebSearchTool.js +6 -1
  358. package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
  359. package/dist/tools.js +31 -2
  360. package/dist/tools.js.map +2 -2
  361. package/dist/types/hooks.js +4 -0
  362. package/dist/types/hooks.js.map +2 -2
  363. package/dist/types/marketplace.js.map +2 -2
  364. package/dist/types/messageGroup.js +36 -0
  365. package/dist/types/messageGroup.js.map +7 -0
  366. package/dist/types/plugin.js.map +2 -2
  367. package/dist/types/thinking.js +1 -0
  368. package/dist/types/thinking.js.map +7 -0
  369. package/dist/utils/BackgroundShellManager.js +136 -39
  370. package/dist/utils/BackgroundShellManager.js.map +2 -2
  371. package/dist/utils/MessageBatchBuffer.js +102 -0
  372. package/dist/utils/MessageBatchBuffer.js.map +7 -0
  373. package/dist/utils/PersistentShell.js +151 -1
  374. package/dist/utils/PersistentShell.js.map +2 -2
  375. package/dist/utils/agentLoader.js +1 -23
  376. package/dist/utils/agentLoader.js.map +2 -2
  377. package/dist/utils/agentTranscripts.js +641 -0
  378. package/dist/utils/agentTranscripts.js.map +7 -0
  379. package/dist/utils/animationManager.js +213 -0
  380. package/dist/utils/animationManager.js.map +7 -0
  381. package/dist/utils/animationSync.js +110 -0
  382. package/dist/utils/animationSync.js.map +7 -0
  383. package/dist/utils/asyncFile.js +215 -0
  384. package/dist/utils/asyncFile.js.map +7 -0
  385. package/dist/utils/backgroundAgentManager.js +231 -0
  386. package/dist/utils/backgroundAgentManager.js.map +7 -0
  387. package/dist/utils/config.js +63 -7
  388. package/dist/utils/config.js.map +2 -2
  389. package/dist/utils/conversationRecovery.js +19 -0
  390. package/dist/utils/conversationRecovery.js.map +2 -2
  391. package/dist/utils/exit.js +73 -0
  392. package/dist/utils/exit.js.map +7 -0
  393. package/dist/utils/format.js +73 -5
  394. package/dist/utils/format.js.map +2 -2
  395. package/dist/utils/generators.js +76 -6
  396. package/dist/utils/generators.js.map +2 -2
  397. package/dist/utils/globalErrorHandler.js +149 -0
  398. package/dist/utils/globalErrorHandler.js.map +7 -0
  399. package/dist/utils/groupHandlers/index.js +8 -0
  400. package/dist/utils/groupHandlers/index.js.map +7 -0
  401. package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
  402. package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
  403. package/dist/utils/groupHandlers/taskHandler.js +104 -0
  404. package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
  405. package/dist/utils/groupHandlers/types.js +1 -0
  406. package/dist/utils/groupHandlers/types.js.map +7 -0
  407. package/dist/utils/logRotation.js +224 -0
  408. package/dist/utils/logRotation.js.map +7 -0
  409. package/dist/utils/marketplaceManager.js +3 -5
  410. package/dist/utils/marketplaceManager.js.map +2 -2
  411. package/dist/utils/memSafety.js +264 -0
  412. package/dist/utils/memSafety.js.map +7 -0
  413. package/dist/utils/messageGroupManager.js +274 -0
  414. package/dist/utils/messageGroupManager.js.map +7 -0
  415. package/dist/utils/messages.js +13 -4
  416. package/dist/utils/messages.js.map +2 -2
  417. package/dist/utils/model.js +119 -15
  418. package/dist/utils/model.js.map +3 -3
  419. package/dist/utils/permissions/filesystem.js +157 -5
  420. package/dist/utils/permissions/filesystem.js.map +2 -2
  421. package/dist/utils/plan/planMode.js +143 -0
  422. package/dist/utils/plan/planMode.js.map +7 -0
  423. package/dist/utils/pluginLoader.js +17 -21
  424. package/dist/utils/pluginLoader.js.map +2 -2
  425. package/dist/utils/ripgrep.js +55 -2
  426. package/dist/utils/ripgrep.js.map +2 -2
  427. package/dist/utils/sanitizeInput.js +32 -0
  428. package/dist/utils/sanitizeInput.js.map +7 -0
  429. package/dist/utils/secureKeyStorage.js +312 -0
  430. package/dist/utils/secureKeyStorage.js.map +7 -0
  431. package/dist/utils/session/sessionPlugins.js +67 -0
  432. package/dist/utils/session/sessionPlugins.js.map +7 -0
  433. package/dist/utils/taskDisplayUtils.js +257 -0
  434. package/dist/utils/taskDisplayUtils.js.map +7 -0
  435. package/dist/utils/teamConfig.js +2 -1
  436. package/dist/utils/teamConfig.js.map +2 -2
  437. package/dist/utils/todoStorage.js +92 -2
  438. package/dist/utils/todoStorage.js.map +2 -2
  439. package/dist/utils/toolTimeout.js +136 -0
  440. package/dist/utils/toolTimeout.js.map +7 -0
  441. package/dist/utils/tooling/safeRender.js +115 -0
  442. package/dist/utils/tooling/safeRender.js.map +7 -0
  443. package/dist/utils/userFriendlyError.js +346 -0
  444. package/dist/utils/userFriendlyError.js.map +7 -0
  445. package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
  446. package/dist/version.js +2 -2
  447. package/dist/version.js.map +1 -1
  448. package/package.json +14 -4
  449. package/scripts/postinstall.js +128 -38
  450. package/dist/commands/agents.js +0 -2086
  451. package/dist/commands/agents.js.map +0 -7
  452. package/dist/commands/build.js +0 -74
  453. package/dist/commands/build.js.map +0 -7
  454. package/dist/commands/compression.js +0 -57
  455. package/dist/commands/compression.js.map +0 -7
  456. package/dist/commands/listen.js +0 -37
  457. package/dist/commands/listen.js.map +0 -7
  458. package/dist/commands/login.js +0 -37
  459. package/dist/commands/login.js.map +0 -7
  460. package/dist/commands/logout.js +0 -33
  461. package/dist/commands/logout.js.map +0 -7
  462. package/dist/commands/mcp.js +0 -40
  463. package/dist/commands/mcp.js.map +0 -7
  464. package/dist/commands/mcp_refresh.js +0 -40
  465. package/dist/commands/mcp_refresh.js.map +0 -7
  466. package/dist/commands/modelstatus.js +0 -21
  467. package/dist/commands/modelstatus.js.map +0 -7
  468. package/dist/commands/onboarding.js +0 -36
  469. package/dist/commands/onboarding.js.map +0 -7
  470. package/dist/commands/plugin-interactive.js +0 -446
  471. package/dist/commands/plugin-interactive.js.map +0 -7
  472. package/dist/commands/pr_comments.js +0 -61
  473. package/dist/commands/pr_comments.js.map +0 -7
  474. package/dist/commands/release-notes.js +0 -30
  475. package/dist/commands/release-notes.js.map +0 -7
  476. package/dist/commands/review.js +0 -51
  477. package/dist/commands/review.js.map +0 -7
  478. package/dist/components/Bug.js +0 -147
  479. package/dist/components/Bug.js.map +0 -7
  480. package/dist/components/ModelSelector.js +0 -2062
  481. package/dist/components/ModelSelector.js.map +0 -7
  482. package/dist/components/ModelStatusDisplay.js +0 -87
  483. package/dist/components/ModelStatusDisplay.js.map +0 -7
  484. package/dist/entrypoints/cli-wrapper.js +0 -61
  485. package/dist/entrypoints/cli-wrapper.js.map +0 -7
  486. package/dist/screens/Doctor.js +0 -22
  487. package/dist/screens/Doctor.js.map +0 -7
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/services/taskRouter.ts"],
4
+ "sourcesContent": ["/**\n * Task Router\n *\n * Intelligent task routing system that analyzes tasks and routes them\n * to the most appropriate model based on complexity, type, and cost.\n */\n\nimport { getModelManager } from '@utils/model'\n\n/**\n * Task complexity levels\n */\nexport type TaskComplexity = 'simple' | 'moderate' | 'complex'\n\n/**\n * Task type categories\n */\nexport type TaskType =\n | 'query' // Simple questions, lookups\n | 'generation' // Code generation, content creation\n | 'review' // Code review, analysis\n | 'reasoning' // Complex logic, problem solving\n | 'creative' // Creative writing, brainstorming\n | 'refactor' // Code refactoring, optimization\n | 'debug' // Debugging, error analysis\n | 'architecture' // System design, architecture\n\n/**\n * Result of task analysis\n */\nexport interface TaskAnalysis {\n /** Estimated task complexity */\n complexity: TaskComplexity\n /** Detected task type */\n type: TaskType\n /** Estimated input tokens */\n estimatedInputTokens: number\n /** Estimated output tokens */\n estimatedOutputTokens: number\n /** Suggested model for this task */\n suggestedModel: string\n /** Confidence score (0-1) */\n confidence: number\n /** Detected patterns that influenced the analysis */\n detectedPatterns: string[]\n}\n\n/**\n * Routing rule configuration\n */\nexport interface RoutingRule {\n /** Pattern to match (complexity-type) */\n pattern: string\n /** Model to route to */\n model: string\n /** Rule priority (lower = higher priority) */\n priority: number\n}\n\n/**\n * Task analysis patterns\n */\ninterface AnalysisPattern {\n /** Pattern name */\n name: string\n /** Regex or keywords to match */\n patterns: RegExp[]\n /** Detected type */\n type: TaskType\n /** Complexity adjustment */\n complexityWeight: number\n}\n\n/**\n * Default routing rules\n */\nconst DEFAULT_ROUTING_RULES: RoutingRule[] = [\n // Simple tasks \u2192 fast model\n { pattern: 'simple-query', model: 'haiku', priority: 1 },\n { pattern: 'simple-generation', model: 'haiku', priority: 1 },\n\n // Moderate tasks \u2192 balanced model\n { pattern: 'moderate-query', model: 'sonnet', priority: 2 },\n { pattern: 'moderate-generation', model: 'sonnet', priority: 2 },\n { pattern: 'moderate-review', model: 'sonnet', priority: 2 },\n { pattern: 'moderate-refactor', model: 'sonnet', priority: 2 },\n { pattern: 'moderate-debug', model: 'sonnet', priority: 2 },\n\n // Complex tasks \u2192 powerful model\n { pattern: 'complex-reasoning', model: 'opus', priority: 3 },\n { pattern: 'complex-architecture', model: 'opus', priority: 3 },\n { pattern: 'complex-generation', model: 'opus', priority: 3 },\n { pattern: 'complex-creative', model: 'opus', priority: 3 },\n\n // Specific task types\n { pattern: '*-architecture', model: 'opus', priority: 0 },\n { pattern: '*-reasoning', model: 'opus', priority: 0 },\n { pattern: '*-review', model: 'sonnet', priority: 1 },\n { pattern: '*-debug', model: 'sonnet', priority: 1 },\n]\n\n/**\n * Analysis patterns for task type detection\n */\nconst ANALYSIS_PATTERNS: AnalysisPattern[] = [\n // Query patterns\n {\n name: 'question',\n patterns: [\n /\\b(what|how|why|when|where|who|which|can you explain)\\b/i,\n /\\?$/,\n /\\b(tell me|show me|help me understand)\\b/i,\n ],\n type: 'query',\n complexityWeight: -0.2,\n },\n\n // Generation patterns\n {\n name: 'generation',\n patterns: [\n /\\b(create|generate|write|build|implement|add|make)\\b/i,\n /\\b(new|feature|function|class|component|module)\\b/i,\n ],\n type: 'generation',\n complexityWeight: 0.1,\n },\n\n // Review patterns\n {\n name: 'review',\n patterns: [\n /\\b(review|check|analyze|examine|inspect|audit)\\b/i,\n /\\b(code review|pull request|pr|merge)\\b/i,\n ],\n type: 'review',\n complexityWeight: 0,\n },\n\n // Reasoning patterns\n {\n name: 'reasoning',\n patterns: [\n /\\b(think|reason|consider|evaluate|compare|decide)\\b/i,\n /\\b(trade-?off|pros and cons|best approach|optimal)\\b/i,\n /\\b(algorithm|complexity|performance|efficiency)\\b/i,\n ],\n type: 'reasoning',\n complexityWeight: 0.3,\n },\n\n // Creative patterns\n {\n name: 'creative',\n patterns: [\n /\\b(creative|brainstorm|innovative|design|imagine)\\b/i,\n /\\b(suggest|propose|come up with|ideas)\\b/i,\n ],\n type: 'creative',\n complexityWeight: 0.2,\n },\n\n // Refactoring patterns\n {\n name: 'refactor',\n patterns: [\n /\\b(refactor|restructure|reorganize|clean up|improve)\\b/i,\n /\\b(optimize|simplify|modularize|extract)\\b/i,\n ],\n type: 'refactor',\n complexityWeight: 0.15,\n },\n\n // Debug patterns\n {\n name: 'debug',\n patterns: [\n /\\b(debug|fix|error|bug|issue|problem|crash)\\b/i,\n /\\b(broken|doesn't work|failing|wrong)\\b/i,\n /\\b(stack trace|exception|undefined|null)\\b/i,\n ],\n type: 'debug',\n complexityWeight: 0.1,\n },\n\n // Architecture patterns\n {\n name: 'architecture',\n patterns: [\n /\\b(architect|design|system|infrastructure|scale)\\b/i,\n /\\b(microservice|monolith|distributed|database)\\b/i,\n /\\b(api design|schema|data model|integration)\\b/i,\n ],\n type: 'architecture',\n complexityWeight: 0.4,\n },\n]\n\n/**\n * Complexity indicators\n */\nconst COMPLEXITY_INDICATORS = {\n simple: [\n /\\b(simple|quick|basic|easy|trivial|small)\\b/i,\n /\\b(one line|single|just|only)\\b/i,\n ],\n complex: [\n /\\b(complex|difficult|challenging|advanced|comprehensive)\\b/i,\n /\\b(entire|whole|all|complete|full|extensive)\\b/i,\n /\\b(multiple|several|many|various)\\b/i,\n /\\b(system|platform|framework|infrastructure)\\b/i,\n ],\n}\n\n/**\n * Task Router for intelligent model selection\n */\nexport class TaskRouter {\n private routingRules: Map<string, string> = new Map()\n private modelManager = getModelManager()\n private customRules: RoutingRule[] = []\n\n constructor(customRules?: RoutingRule[]) {\n // Initialize with default rules\n this.loadRules(DEFAULT_ROUTING_RULES)\n\n // Add custom rules if provided\n if (customRules) {\n this.customRules = customRules\n this.loadRules(customRules)\n }\n }\n\n /**\n * Load routing rules into the map\n */\n private loadRules(rules: RoutingRule[]): void {\n // Sort by priority (lower = higher priority)\n const sorted = [...rules].sort((a, b) => a.priority - b.priority)\n\n for (const rule of sorted) {\n this.routingRules.set(rule.pattern, rule.model)\n }\n }\n\n /**\n * Analyze a task and return detailed analysis\n */\n analyzeTask(task: string): TaskAnalysis {\n const detectedPatterns: string[] = []\n let complexityScore = 0.5 // Start at moderate\n let primaryType: TaskType = 'query'\n let typeMatchCount = 0\n\n // Detect task type from patterns\n for (const pattern of ANALYSIS_PATTERNS) {\n let matches = 0\n for (const regex of pattern.patterns) {\n if (regex.test(task)) {\n matches++\n }\n }\n\n if (matches > 0) {\n detectedPatterns.push(pattern.name)\n complexityScore +=\n pattern.complexityWeight * (matches / pattern.patterns.length)\n\n if (matches > typeMatchCount) {\n typeMatchCount = matches\n primaryType = pattern.type\n }\n }\n }\n\n // Detect complexity indicators\n for (const regex of COMPLEXITY_INDICATORS.simple) {\n if (regex.test(task)) {\n complexityScore -= 0.2\n detectedPatterns.push('simple-indicator')\n }\n }\n\n for (const regex of COMPLEXITY_INDICATORS.complex) {\n if (regex.test(task)) {\n complexityScore += 0.2\n detectedPatterns.push('complex-indicator')\n }\n }\n\n // Adjust for task length (longer tasks tend to be more complex)\n const wordCount = task.split(/\\s+/).length\n if (wordCount < 10) {\n complexityScore -= 0.1\n } else if (wordCount > 50) {\n complexityScore += 0.1\n } else if (wordCount > 100) {\n complexityScore += 0.2\n }\n\n // Normalize complexity score\n complexityScore = Math.max(0, Math.min(1, complexityScore))\n\n // Determine complexity level\n let complexity: TaskComplexity\n if (complexityScore < 0.35) {\n complexity = 'simple'\n } else if (complexityScore < 0.65) {\n complexity = 'moderate'\n } else {\n complexity = 'complex'\n }\n\n // Estimate tokens\n const estimatedInputTokens = Math.ceil(task.length / 4)\n const estimatedOutputTokens = this.estimateOutputTokens(\n complexity,\n primaryType,\n )\n\n // Get suggested model\n const suggestedModel = this.route(complexity, primaryType)\n\n // Calculate confidence\n const confidence =\n typeMatchCount > 0\n ? Math.min(\n 1,\n 0.5 + typeMatchCount * 0.15 + detectedPatterns.length * 0.05,\n )\n : 0.5\n\n return {\n complexity,\n type: primaryType,\n estimatedInputTokens,\n estimatedOutputTokens,\n suggestedModel,\n confidence,\n detectedPatterns: [...new Set(detectedPatterns)],\n }\n }\n\n /**\n * Route a task to the appropriate model\n */\n route(complexity: TaskComplexity, type: TaskType): string {\n // Try exact match\n const exactKey = `${complexity}-${type}`\n if (this.routingRules.has(exactKey)) {\n return this.routingRules.get(exactKey)!\n }\n\n // Try wildcard match\n const wildcardKey = `*-${type}`\n if (this.routingRules.has(wildcardKey)) {\n return this.routingRules.get(wildcardKey)!\n }\n\n // Default based on complexity\n switch (complexity) {\n case 'simple':\n return 'haiku'\n case 'moderate':\n return 'sonnet'\n case 'complex':\n return 'opus'\n }\n }\n\n /**\n * Route a task directly from task text\n */\n routeTask(task: string): string {\n const analysis = this.analyzeTask(task)\n return analysis.suggestedModel\n }\n\n /**\n * Estimate output tokens based on task type and complexity\n */\n private estimateOutputTokens(\n complexity: TaskComplexity,\n type: TaskType,\n ): number {\n const baseTokens: Record<TaskType, number> = {\n query: 200,\n generation: 500,\n review: 400,\n reasoning: 600,\n creative: 400,\n refactor: 800,\n debug: 500,\n architecture: 1000,\n }\n\n const multipliers: Record<TaskComplexity, number> = {\n simple: 0.5,\n moderate: 1.0,\n complex: 2.0,\n }\n\n return Math.ceil(baseTokens[type] * multipliers[complexity])\n }\n\n /**\n * Add a custom routing rule\n */\n addRule(rule: RoutingRule): void {\n this.customRules.push(rule)\n this.routingRules.set(rule.pattern, rule.model)\n }\n\n /**\n * Remove a routing rule\n */\n removeRule(pattern: string): boolean {\n const index = this.customRules.findIndex(r => r.pattern === pattern)\n if (index >= 0) {\n this.customRules.splice(index, 1)\n this.routingRules.delete(pattern)\n return true\n }\n return false\n }\n\n /**\n * Get all current routing rules\n */\n getRules(): RoutingRule[] {\n return [...DEFAULT_ROUTING_RULES, ...this.customRules]\n }\n\n /**\n * Get cost estimate for a task\n */\n estimateCost(task: string): {\n model: string\n estimatedInputTokens: number\n estimatedOutputTokens: number\n estimatedTotalTokens: number\n } {\n const analysis = this.analyzeTask(task)\n return {\n model: analysis.suggestedModel,\n estimatedInputTokens: analysis.estimatedInputTokens,\n estimatedOutputTokens: analysis.estimatedOutputTokens,\n estimatedTotalTokens:\n analysis.estimatedInputTokens + analysis.estimatedOutputTokens,\n }\n }\n}\n\n// Singleton instance\nlet routerInstance: TaskRouter | null = null\n\n/**\n * Get the task router instance\n */\nexport function getTaskRouter(): TaskRouter {\n if (!routerInstance) {\n routerInstance = new TaskRouter()\n }\n return routerInstance\n}\n\n/**\n * Reset the task router instance (useful for testing)\n */\nexport function resetTaskRouter(): void {\n routerInstance = null\n}\n\n/**\n * Route a task to the appropriate model\n */\nexport function routeTask(task: string): string {\n return getTaskRouter().routeTask(task)\n}\n\n/**\n * Analyze a task and return detailed analysis\n */\nexport function analyzeTask(task: string): TaskAnalysis {\n return getTaskRouter().analyzeTask(task)\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -95,16 +95,23 @@ ${prompt}` : prompt;
95
95
  return DESCRIPTION;
96
96
  },
97
97
  renderResultForAssistant(data) {
98
- return data.map((block) => block.text).join("\n");
98
+ if (!data || !Array.isArray(data)) {
99
+ return "Analysis completed";
100
+ }
101
+ return data.filter((block) => block != null).map((block) => block.text || "").join("\n");
99
102
  },
100
103
  renderToolUseMessage(input) {
101
- return Object.entries(input).map(([key, value]) => `${key}: ${JSON.stringify(value)}`).join(", ");
104
+ return Object.entries(input || {}).map(([key, value]) => `${key}: ${JSON.stringify(value)}`).join(", ");
102
105
  },
103
106
  renderToolResultMessage(content) {
107
+ if (!content || !Array.isArray(content)) {
108
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(HighlightedCode, { code: "Analysis completed", language: "markdown" }));
109
+ }
110
+ const code = content.filter((block) => block != null).map((block) => block.text || "").join("\n");
104
111
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
105
112
  HighlightedCode,
106
113
  {
107
- code: content.map((_) => _.text).join("\n"),
114
+ code: code || "Analysis completed",
108
115
  language: "markdown"
109
116
  }
110
117
  ));
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/ArchitectTool/ArchitectTool.tsx"],
4
- "sourcesContent": ["import type { TextBlock } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { Box } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport type { Tool } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { HighlightedCode } from '@components/HighlightedCode'\nimport { getContext } from '@context'\nimport { Message, query } from '@query'\nimport { lastX } from '@utils/generators'\nimport { createUserMessage } from '@utils/messages'\nimport { BashTool } from '@tools/BashTool/BashTool'\nimport { FileReadTool } from '@tools/FileReadTool/FileReadTool'\nimport { FileWriteTool } from '@tools/FileWriteTool/FileWriteTool'\nimport { GlobTool } from '@tools/GlobTool/GlobTool'\nimport { GrepTool } from '@tools/GrepTool/GrepTool'\nimport { LSTool } from '@tools/lsTool/lsTool'\nimport { ARCHITECT_SYSTEM_PROMPT, DESCRIPTION } from './prompt'\n\nconst FS_EXPLORATION_TOOLS: Tool[] = [\n BashTool,\n LSTool,\n FileReadTool,\n FileWriteTool,\n GlobTool,\n GrepTool,\n]\n\nconst inputSchema = z.strictObject({\n prompt: z\n .string()\n .describe('The technical request or coding task to analyze'),\n context: z\n .string()\n .describe('Optional context from previous conversation or system state')\n .optional(),\n})\n\nexport const ArchitectTool = {\n name: 'Architect',\n async description() {\n return DESCRIPTION\n },\n inputSchema,\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true // ArchitectTool is read-only, safe for concurrent execution\n },\n userFacingName() {\n return 'Architect'\n },\n async isEnabled() {\n return false\n },\n needsPermissions() {\n return false\n },\n async *call({ prompt, context }, toolUseContext) {\n const content = context\n ? `<context>${context}</context>\\n\\n${prompt}`\n : prompt\n\n const userMessage = createUserMessage(content)\n\n const messages: Message[] = [userMessage]\n\n // We only allow the file exploration tools to be used in the architect tool\n const allowedTools = (toolUseContext.options?.tools ?? []).filter(_ =>\n FS_EXPLORATION_TOOLS.map(_ => _.name).includes(_.name),\n )\n\n // Create a dummy canUseTool function since this tool controls its own tool usage\n const canUseTool = async () => ({ result: true as const })\n\n const lastResponse = await lastX(\n query(\n messages,\n [ARCHITECT_SYSTEM_PROMPT],\n await getContext(),\n canUseTool,\n {\n ...toolUseContext,\n setToolJSX: () => {}, // Dummy function since ArchitectTool doesn't use UI\n options: {\n commands: toolUseContext.options?.commands || [],\n forkNumber: toolUseContext.options?.forkNumber || 0,\n messageLogName: toolUseContext.options?.messageLogName || 'default',\n verbose: toolUseContext.options?.verbose || false,\n safeMode: toolUseContext.options?.safeMode || false,\n maxThinkingTokens: toolUseContext.options?.maxThinkingTokens || 0,\n ...toolUseContext.options,\n tools: allowedTools,\n },\n },\n ),\n )\n\n if (lastResponse.type !== 'assistant') {\n throw new Error(`Invalid response from API`)\n }\n\n const data = lastResponse.message.content.filter(_ => _.type === 'text')\n yield {\n type: 'result',\n data,\n resultForAssistant: this.renderResultForAssistant(data),\n }\n },\n async prompt() {\n return DESCRIPTION\n },\n renderResultForAssistant(data: TextBlock[]): string {\n return data.map(block => block.text).join('\\n')\n },\n renderToolUseMessage(input) {\n return Object.entries(input)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ')\n },\n renderToolResultMessage(content) {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <HighlightedCode\n code={content.map(_ => _.text).join('\\n')}\n language=\"markdown\"\n />\n </Box>\n )\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n} satisfies Tool<typeof inputSchema, TextBlock[]>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { TextBlock } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { Box } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport type { Tool } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { HighlightedCode } from '@components/HighlightedCode'\nimport { getContext } from '@context'\nimport { Message, query } from '@query'\nimport { lastX } from '@utils/generators'\nimport { createUserMessage } from '@utils/messages'\nimport { BashTool } from '@tools/BashTool/BashTool'\nimport { FileReadTool } from '@tools/FileReadTool/FileReadTool'\nimport { FileWriteTool } from '@tools/FileWriteTool/FileWriteTool'\nimport { GlobTool } from '@tools/GlobTool/GlobTool'\nimport { GrepTool } from '@tools/GrepTool/GrepTool'\nimport { LSTool } from '@tools/lsTool/lsTool'\nimport { ARCHITECT_SYSTEM_PROMPT, DESCRIPTION } from './prompt'\n\nconst FS_EXPLORATION_TOOLS: Tool[] = [\n BashTool,\n LSTool,\n FileReadTool,\n FileWriteTool,\n GlobTool,\n GrepTool,\n]\n\nconst inputSchema = z.strictObject({\n prompt: z\n .string()\n .describe('The technical request or coding task to analyze'),\n context: z\n .string()\n .describe('Optional context from previous conversation or system state')\n .optional(),\n})\n\nexport const ArchitectTool = {\n name: 'Architect',\n async description() {\n return DESCRIPTION\n },\n inputSchema,\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true // ArchitectTool is read-only, safe for concurrent execution\n },\n userFacingName() {\n return 'Architect'\n },\n async isEnabled() {\n return false\n },\n needsPermissions() {\n return false\n },\n async *call({ prompt, context }, toolUseContext) {\n const content = context\n ? `<context>${context}</context>\\n\\n${prompt}`\n : prompt\n\n const userMessage = createUserMessage(content)\n\n const messages: Message[] = [userMessage]\n\n // We only allow the file exploration tools to be used in the architect tool\n const allowedTools = (toolUseContext.options?.tools ?? []).filter(_ =>\n FS_EXPLORATION_TOOLS.map(_ => _.name).includes(_.name),\n )\n\n // Create a dummy canUseTool function since this tool controls its own tool usage\n const canUseTool = async () => ({ result: true as const })\n\n const lastResponse = await lastX(\n query(\n messages,\n [ARCHITECT_SYSTEM_PROMPT],\n await getContext(),\n canUseTool,\n {\n ...toolUseContext,\n setToolJSX: () => {}, // Dummy function since ArchitectTool doesn't use UI\n options: {\n commands: toolUseContext.options?.commands || [],\n forkNumber: toolUseContext.options?.forkNumber || 0,\n messageLogName: toolUseContext.options?.messageLogName || 'default',\n verbose: toolUseContext.options?.verbose || false,\n safeMode: toolUseContext.options?.safeMode || false,\n maxThinkingTokens: toolUseContext.options?.maxThinkingTokens || 0,\n ...toolUseContext.options,\n tools: allowedTools,\n },\n },\n ),\n )\n\n if (lastResponse.type !== 'assistant') {\n throw new Error(`Invalid response from API`)\n }\n\n const data = lastResponse.message.content.filter(_ => _.type === 'text')\n yield {\n type: 'result',\n data,\n resultForAssistant: this.renderResultForAssistant(data),\n }\n },\n async prompt() {\n return DESCRIPTION\n },\n renderResultForAssistant(data: TextBlock[]): string {\n // Guard against undefined or null data\n if (!data || !Array.isArray(data)) {\n return 'Analysis completed'\n }\n return data\n .filter(block => block != null)\n .map(block => block.text || '')\n .join('\\n')\n },\n renderToolUseMessage(input) {\n return Object.entries(input || {})\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ')\n },\n renderToolResultMessage(content) {\n // Guard against undefined or null content\n if (!content || !Array.isArray(content)) {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <HighlightedCode code=\"Analysis completed\" language=\"markdown\" />\n </Box>\n )\n }\n\n const code = content\n .filter(block => block != null)\n .map(block => block.text || '')\n .join('\\n')\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <HighlightedCode\n code={code || 'Analysis completed'}\n language=\"markdown\"\n />\n </Box>\n )\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n} satisfies Tool<typeof inputSchema, TextBlock[]>\n"],
5
+ "mappings": "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",
6
6
  "names": ["_"]
7
7
  }
@@ -159,6 +159,9 @@ Question: What are the most effective React optimization techniques for handling
159
159
  renderToolResultMessage(content) {
160
160
  const verbose = true;
161
161
  const theme = getTheme();
162
+ if (!content) {
163
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Consultation completed"));
164
+ }
162
165
  if (typeof content === "object" && content && "expertAnswer" in content) {
163
166
  const expertResult = content;
164
167
  const isError = expertResult.expertAnswer.startsWith("Error") || expertResult.expertAnswer.includes("failed");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/AskExpertModelTool/AskExpertModelTool.tsx"],
4
- "sourcesContent": ["import * as React from 'react'\nimport { Box, Text } from 'ink'\nimport { z } from 'zod'\nimport { Tool, ValidationResult } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { getModelManager } from '@utils/model'\nimport { getTheme } from '@utils/theme'\nimport {\n createUserMessage,\n createAssistantMessage,\n INTERRUPT_MESSAGE,\n} from '@utils/messages'\nimport { logError } from '@utils/log'\nimport {\n createExpertChatSession,\n loadExpertChatSession,\n getSessionMessages,\n addMessageToSession,\n} from '@utils/expertChatStorage'\nimport { queryLLM } from '@services/claude'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { applyMarkdown } from '@utils/markdown'\n\nexport const inputSchema = z.strictObject({\n question: z\n .string()\n .describe(\n 'COMPLETE SELF-CONTAINED QUESTION: Must include full background context, relevant details, and a clear independent question. The expert model will receive ONLY this content with no access to previous conversation or external context. Structure as: 1) Background/Context 2) Specific situation/problem 3) Clear question. Ensure the expert can fully understand and respond without needing additional information.',\n ),\n expert_model: z\n .string()\n .describe(\n 'The expert model to use (e.g., gpt-5, claude-3-5-sonnet-20241022)',\n ),\n chat_session_id: z\n .string()\n .describe(\n 'Chat session ID: use \"new\" for new session or existing session ID',\n ),\n})\n\ntype In = typeof inputSchema\nexport type Out = {\n chatSessionId: string\n expertModelName: string\n expertAnswer: string\n}\n\nexport const AskExpertModelTool = {\n name: 'AskExpertModel',\n async description() {\n return 'Consult external AI models for expert opinions and analysis'\n },\n async prompt() {\n return `Ask a question to a specific external AI model for expert analysis.\n\nThis tool allows you to consult different AI models for their unique perspectives and expertise.\n\nCRITICAL REQUIREMENT FOR QUESTION PARAMETER:\nThe question MUST be completely self-contained and include:\n1. FULL BACKGROUND CONTEXT - All relevant information the expert needs\n2. SPECIFIC SITUATION - Clear description of the current scenario/problem\n3. INDEPENDENT QUESTION - What exactly you want the expert to analyze/answer\n\nThe expert model receives ONLY your question content with NO access to:\n- Previous conversation history (unless using existing session) \n- Current codebase or file context\n- User's current task or project details\n\nIMPORTANT: This tool is for asking questions to models, not for task execution.\n- Use when you need a specific model's opinion or analysis\n- Use when you want to compare different models' responses\n- Use the @ask-[model] format when available\n\nThe expert_model parameter accepts:\n- OpenAI: gpt-4, gpt-5, o1-preview\n- Anthropic: claude-3-5-sonnet, claude-3-opus \n- Others: kimi, gemini-pro, mixtral\n\nExample of well-structured question:\n\"Background: I'm working on a React TypeScript application with performance issues. The app renders a large list of 10,000 items using a simple map() function, causing UI freezing.\n\nCurrent situation: Users report 3-5 second delays when scrolling through the list. The component re-renders the entire list on every state change.\n\nQuestion: What are the most effective React optimization techniques for handling large lists, and how should I prioritize implementing virtualization vs memoization vs other approaches?\"`\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n inputSchema,\n userFacingName() {\n return 'AskExpertModel'\n },\n async isEnabled() {\n return true\n },\n needsPermissions(): boolean {\n return false\n },\n async validateInput(\n { question, expert_model, chat_session_id },\n context?: any,\n ): Promise<ValidationResult> {\n if (!question.trim()) {\n return { result: false, message: 'Question cannot be empty' }\n }\n\n if (!expert_model.trim()) {\n return { result: false, message: 'Expert model must be specified' }\n }\n\n if (!chat_session_id.trim()) {\n return {\n result: false,\n message:\n 'Chat session ID must be specified (use \"new\" for new session)',\n }\n }\n\n // Check if trying to consult the same model we're currently running\n try {\n const modelManager = getModelManager()\n\n // Get current model based on context\n let currentModel: string\n if (context?.agentId && context?.options?.model) {\n // In subagent context (Task tool)\n currentModel = context.options.model\n } else {\n // In main agent context or after model switch\n currentModel = modelManager.getModelName('main') || ''\n }\n\n // Normalize model names for comparison\n const normalizedExpert = expert_model\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '')\n const normalizedCurrent = currentModel\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '')\n\n if (normalizedExpert === normalizedCurrent) {\n return {\n result: false,\n message: `You are already running as ${currentModel}. Consulting the same model would be redundant. Please choose a different model or handle the task directly.`,\n }\n }\n } catch (e) {\n // If we can't determine current model, allow the request\n debugLogger.error('AskExpertModel', {\n message: 'Could not determine current model',\n error: e,\n })\n }\n\n // Validate that the model exists and is available\n try {\n const modelManager = getModelManager()\n const modelResolution = modelManager.resolveModelWithInfo(expert_model)\n\n if (!modelResolution.success) {\n const availableModels = modelManager.getAllAvailableModelNames()\n if (availableModels.length > 0) {\n return {\n result: false,\n message: `Model '${expert_model}' is not configured. Available models: ${availableModels.join(', ')}. Check if any available model closely matches the user's request (e.g., 'kimi' matches 'kimi-k2-0711-preview'). If there's a strong match, auto retry using the correct model name. If no close match exists, inform the user that '${expert_model}' needs to be configured using /model command.`,\n }\n } else {\n return {\n result: false,\n message: `Model '${expert_model}' not found and no models are currently configured in the system. Inform the user that models need to be configured first using the /model command.`,\n }\n }\n }\n } catch (error) {\n console.error('Model validation error in AskExpertModelTool:', error)\n logError(error)\n return {\n result: false,\n message: `Failed to validate expert model '${expert_model}'. Please check your model configuration.`,\n }\n }\n\n return { result: true }\n },\n\n renderToolUseMessage(\n { question, expert_model, chat_session_id },\n { verbose },\n ) {\n if (!question || !expert_model) return null\n const isNewSession = chat_session_id === 'new'\n const sessionDisplay = isNewSession\n ? 'new session'\n : `session ${chat_session_id.substring(0, 5)}...`\n const theme = getTheme()\n\n if (verbose) {\n return (\n <Box flexDirection=\"column\">\n <Text bold color=\"yellow\">\n {expert_model}\n </Text>\n <Text color={theme.secondaryText}>{sessionDisplay}</Text>\n <Box marginTop={1}>\n <Text color={theme.text}>\n {question.length > 300\n ? question.substring(0, 300) + '...'\n : question}\n </Text>\n </Box>\n </Box>\n )\n }\n return (\n <Box flexDirection=\"column\">\n <Text bold color=\"yellow\">\n {expert_model}{' '}\n </Text>\n <Text color={theme.secondaryText} dimColor>\n ({sessionDisplay})\n </Text>\n </Box>\n )\n },\n\n renderToolResultMessage(content) {\n const verbose = true // Show more content\n const theme = getTheme()\n\n if (typeof content === 'object' && content && 'expertAnswer' in content) {\n const expertResult = content as Out\n const isError =\n expertResult.expertAnswer.startsWith('Error') ||\n expertResult.expertAnswer.includes('failed')\n const isInterrupted = expertResult.chatSessionId === 'interrupted'\n\n if (isInterrupted) {\n return (\n <Box flexDirection=\"row\">\n <Text color={theme.secondaryText}>Consultation interrupted</Text>\n </Box>\n )\n }\n\n const answerText = verbose\n ? expertResult.expertAnswer.trim()\n : expertResult.expertAnswer.length > 500\n ? expertResult.expertAnswer.substring(0, 500) + '...'\n : expertResult.expertAnswer.trim()\n\n if (isError) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"red\">{answerText}</Text>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text bold color={theme.text}>\n Response from {expertResult.expertModelName}:\n </Text>\n <Box marginTop={1}>\n <Text color={theme.text}>{applyMarkdown(answerText)}</Text>\n </Box>\n <Box marginTop={1}>\n <Text color={theme.secondaryText} dimColor>\n Session: {expertResult.chatSessionId.substring(0, 8)}\n </Text>\n </Box>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"row\">\n <Text color={theme.secondaryText}>Consultation completed</Text>\n </Box>\n )\n },\n\n renderResultForAssistant(output: Out): string {\n return `[Expert consultation completed]\nExpert Model: ${output.expertModelName}\nSession ID: ${output.chatSessionId}\nTo continue this conversation with context preservation, use this Session ID in your next AskExpertModel call to maintain the full conversation history and context.\n\n${output.expertAnswer}`\n },\n\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n\n async *call(\n { question, expert_model, chat_session_id },\n { abortController, readFileTimestamps },\n ) {\n const expertModel = expert_model\n\n let sessionId: string\n let isInterrupted = false\n\n // Set up abort listener (following TaskTool pattern)\n const abortListener = () => {\n isInterrupted = true\n }\n abortController.signal.addEventListener('abort', abortListener)\n\n try {\n // Initial abort check\n if (abortController.signal.aborted) {\n return yield* this.handleInterrupt()\n }\n // Session management with error handling\n if (chat_session_id === 'new') {\n try {\n const session = createExpertChatSession(expertModel)\n sessionId = session.sessionId\n } catch (error) {\n console.error('Failed to create new expert chat session:', error)\n logError(error)\n throw new Error('Failed to create new chat session')\n }\n } else {\n sessionId = chat_session_id\n try {\n const session = loadExpertChatSession(sessionId)\n if (!session) {\n // Session doesn't exist, create new one\n const newSession = createExpertChatSession(expertModel)\n sessionId = newSession.sessionId\n }\n } catch (error) {\n console.error('Failed to load expert chat session:', error)\n logError(error)\n // Fallback: create new session\n try {\n const newSession = createExpertChatSession(expertModel)\n sessionId = newSession.sessionId\n } catch (createError) {\n console.error(\n 'Failed to create fallback expert chat session:',\n createError,\n )\n logError(createError)\n throw new Error('Unable to create or load chat session')\n }\n }\n }\n\n // Check for cancellation before loading history\n if (isInterrupted || abortController.signal.aborted) {\n return yield* this.handleInterrupt()\n }\n\n // Load history and prepare messages with error handling\n let historyMessages: Array<{ role: string; content: string }>\n try {\n historyMessages = getSessionMessages(sessionId)\n } catch (error) {\n console.error('Failed to load session messages:', error)\n logError(error)\n historyMessages = [] // Fallback to empty history\n }\n\n const messages = [...historyMessages, { role: 'user', content: question }]\n\n let systemMessages\n try {\n systemMessages = messages.map(msg =>\n msg.role === 'user'\n ? createUserMessage(msg.content)\n : createAssistantMessage(msg.content),\n )\n } catch (error) {\n console.error('Failed to create system messages:', error)\n logError(error)\n throw new Error('Failed to prepare conversation messages')\n }\n\n // Check for cancellation before model call\n if (isInterrupted || abortController.signal.aborted) {\n return yield* this.handleInterrupt()\n }\n\n // Yield progress message to show we're connecting\n yield {\n type: 'progress',\n content: createAssistantMessage(\n `Connecting to ${expertModel}... (timeout: 5 minutes)`,\n ),\n }\n\n // Call model with comprehensive error handling and timeout\n let response\n try {\n // Debug: Log the model we're trying to use (using global debug logger)\n const modelManager = getModelManager()\n const modelResolution = modelManager.resolveModelWithInfo(expertModel)\n\n debugLogger.api('EXPERT_MODEL_RESOLUTION', {\n requestedModel: expertModel,\n success: modelResolution.success,\n profileName: modelResolution.profile?.name,\n profileModelName: modelResolution.profile?.modelName,\n provider: modelResolution.profile?.provider,\n isActive: modelResolution.profile?.isActive,\n error: modelResolution.error,\n })\n\n // Create a timeout promise to prevent hanging\n const timeoutMs = 300000 // 300 seconds (5 minutes) timeout for external models\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => {\n reject(\n new Error(\n `Expert model query timed out after ${timeoutMs / 1000}s`,\n ),\n )\n }, timeoutMs)\n })\n\n // Race between the query and timeout\n response = await Promise.race([\n queryLLM(\n systemMessages,\n [], // no system prompt - let expert model use its default behavior\n 0, // no thinking tokens needed\n [], // no tools needed\n abortController.signal,\n {\n safeMode: false,\n model: expertModel,\n prependCLISysprompt: false, // KEY: avoid injecting CLI context\n },\n ),\n timeoutPromise,\n ])\n } catch (error: any) {\n console.error('Expert model query failed:', error)\n logError(error)\n\n // Check for specific error types\n if (\n error.name === 'AbortError' ||\n abortController.signal?.aborted ||\n isInterrupted\n ) {\n return yield* this.handleInterrupt()\n }\n\n if (error.message?.includes('timed out')) {\n throw new Error(\n `Expert model '${expertModel}' timed out after 5 minutes.\\n\\n` +\n `Suggestions:\\n` +\n ` - The model might be experiencing high load\\n` +\n ` - Try a different model or retry later\\n` +\n ` - Consider breaking down your question into smaller parts`,\n )\n }\n\n if (error.message?.includes('rate limit')) {\n throw new Error(\n `Rate limit exceeded for ${expertModel}.\\n\\n` +\n `Please wait a moment and try again, or use a different model.`,\n )\n }\n\n if (error.message?.includes('invalid api key')) {\n throw new Error(\n `Invalid API key for ${expertModel}.\\n\\n` +\n `Please check your model configuration with /model command.`,\n )\n }\n\n if (\n error.message?.includes('model not found') ||\n error.message?.includes('Failed to resolve model')\n ) {\n // Provide helpful model guidance in runtime errors too\n try {\n const modelManager = getModelManager()\n const availableModels = modelManager.getAllAvailableModelNames()\n if (availableModels.length > 0) {\n throw new Error(\n `Model '${expertModel}' is not configured. Available models: ${availableModels.join(', ')}. Check if any available model closely matches the user's request (e.g., 'kimi' matches 'kimi-k2-0711-preview'). If there's a strong match, auto retry using the correct model name. If no close match exists, inform the user that '${expertModel}' needs to be configured using /model command.`,\n )\n } else {\n throw new Error(\n `Model '${expertModel}' not found and no models are currently configured in the system. Inform the user that models need to be configured first using the /model command.`,\n )\n }\n } catch (modelError) {\n // If we can't get model list, fall back to simple error\n throw new Error(\n `Model '${expertModel}' not found. Please check model configuration or inform user about the issue.`,\n )\n }\n }\n\n // Generic fallback\n throw new Error(\n `Expert model query failed: ${error.message || 'Unknown error'}`,\n )\n }\n\n // Extract answer with error handling\n let expertAnswer: string\n try {\n if (!response?.message?.content) {\n throw new Error('No content in expert response')\n }\n\n expertAnswer = response.message.content\n .filter(block => block.type === 'text')\n .map(block => (block as any).text)\n .join('\\n')\n\n if (!expertAnswer.trim()) {\n throw new Error('Expert response was empty')\n }\n } catch (error) {\n console.error('Failed to extract expert answer:', error)\n logError(error)\n throw new Error('Failed to process expert response')\n }\n\n // Save conversation with error handling\n try {\n addMessageToSession(sessionId, 'user', question)\n addMessageToSession(sessionId, 'assistant', expertAnswer)\n } catch (error) {\n console.error('Failed to save conversation to session:', error)\n logError(error)\n // Don't throw here - we got a valid response, saving is non-critical\n }\n\n const result: Out = {\n chatSessionId: sessionId,\n expertModelName: expertModel,\n expertAnswer: expertAnswer,\n }\n\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n } catch (error: any) {\n // Check if error is due to cancellation\n if (\n error.name === 'AbortError' ||\n abortController.signal?.aborted ||\n isInterrupted\n ) {\n return yield* this.handleInterrupt()\n }\n\n console.error('AskExpertModelTool execution failed:', error)\n logError(error)\n\n // Ensure we have a valid sessionId for error response\n const errorSessionId = sessionId || 'error-session'\n\n const errorMessage =\n error.message || 'Expert consultation failed with unknown error'\n const result: Out = {\n chatSessionId: errorSessionId,\n expertModelName: expertModel,\n expertAnswer: `\u274C ${errorMessage}`,\n }\n\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n } finally {\n // Clean up event listener\n abortController.signal.removeEventListener('abort', abortListener)\n }\n },\n\n // Unified interrupt handling method (following TaskTool pattern)\n async *handleInterrupt() {\n yield {\n type: 'result',\n data: {\n chatSessionId: 'interrupted',\n expertModelName: 'cancelled',\n expertAnswer: INTERRUPT_MESSAGE,\n },\n resultForAssistant: INTERRUPT_MESSAGE,\n }\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react'\nimport { Box, Text } from 'ink'\nimport { z } from 'zod'\nimport { Tool, ValidationResult } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { getModelManager } from '@utils/model'\nimport { getTheme } from '@utils/theme'\nimport {\n createUserMessage,\n createAssistantMessage,\n INTERRUPT_MESSAGE,\n} from '@utils/messages'\nimport { logError } from '@utils/log'\nimport {\n createExpertChatSession,\n loadExpertChatSession,\n getSessionMessages,\n addMessageToSession,\n} from '@utils/expertChatStorage'\nimport { queryLLM } from '@services/claude'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { applyMarkdown } from '@utils/markdown'\n\nexport const inputSchema = z.strictObject({\n question: z\n .string()\n .describe(\n 'COMPLETE SELF-CONTAINED QUESTION: Must include full background context, relevant details, and a clear independent question. The expert model will receive ONLY this content with no access to previous conversation or external context. Structure as: 1) Background/Context 2) Specific situation/problem 3) Clear question. Ensure the expert can fully understand and respond without needing additional information.',\n ),\n expert_model: z\n .string()\n .describe(\n 'The expert model to use (e.g., gpt-5, claude-3-5-sonnet-20241022)',\n ),\n chat_session_id: z\n .string()\n .describe(\n 'Chat session ID: use \"new\" for new session or existing session ID',\n ),\n})\n\ntype In = typeof inputSchema\nexport type Out = {\n chatSessionId: string\n expertModelName: string\n expertAnswer: string\n}\n\nexport const AskExpertModelTool = {\n name: 'AskExpertModel',\n async description() {\n return 'Consult external AI models for expert opinions and analysis'\n },\n async prompt() {\n return `Ask a question to a specific external AI model for expert analysis.\n\nThis tool allows you to consult different AI models for their unique perspectives and expertise.\n\nCRITICAL REQUIREMENT FOR QUESTION PARAMETER:\nThe question MUST be completely self-contained and include:\n1. FULL BACKGROUND CONTEXT - All relevant information the expert needs\n2. SPECIFIC SITUATION - Clear description of the current scenario/problem\n3. INDEPENDENT QUESTION - What exactly you want the expert to analyze/answer\n\nThe expert model receives ONLY your question content with NO access to:\n- Previous conversation history (unless using existing session) \n- Current codebase or file context\n- User's current task or project details\n\nIMPORTANT: This tool is for asking questions to models, not for task execution.\n- Use when you need a specific model's opinion or analysis\n- Use when you want to compare different models' responses\n- Use the @ask-[model] format when available\n\nThe expert_model parameter accepts:\n- OpenAI: gpt-4, gpt-5, o1-preview\n- Anthropic: claude-3-5-sonnet, claude-3-opus \n- Others: kimi, gemini-pro, mixtral\n\nExample of well-structured question:\n\"Background: I'm working on a React TypeScript application with performance issues. The app renders a large list of 10,000 items using a simple map() function, causing UI freezing.\n\nCurrent situation: Users report 3-5 second delays when scrolling through the list. The component re-renders the entire list on every state change.\n\nQuestion: What are the most effective React optimization techniques for handling large lists, and how should I prioritize implementing virtualization vs memoization vs other approaches?\"`\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n inputSchema,\n userFacingName() {\n return 'AskExpertModel'\n },\n async isEnabled() {\n return true\n },\n needsPermissions(): boolean {\n return false\n },\n async validateInput(\n { question, expert_model, chat_session_id },\n context?: any,\n ): Promise<ValidationResult> {\n if (!question.trim()) {\n return { result: false, message: 'Question cannot be empty' }\n }\n\n if (!expert_model.trim()) {\n return { result: false, message: 'Expert model must be specified' }\n }\n\n if (!chat_session_id.trim()) {\n return {\n result: false,\n message:\n 'Chat session ID must be specified (use \"new\" for new session)',\n }\n }\n\n // Check if trying to consult the same model we're currently running\n try {\n const modelManager = getModelManager()\n\n // Get current model based on context\n let currentModel: string\n if (context?.agentId && context?.options?.model) {\n // In subagent context (Task tool)\n currentModel = context.options.model\n } else {\n // In main agent context or after model switch\n currentModel = modelManager.getModelName('main') || ''\n }\n\n // Normalize model names for comparison\n const normalizedExpert = expert_model\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '')\n const normalizedCurrent = currentModel\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '')\n\n if (normalizedExpert === normalizedCurrent) {\n return {\n result: false,\n message: `You are already running as ${currentModel}. Consulting the same model would be redundant. Please choose a different model or handle the task directly.`,\n }\n }\n } catch (e) {\n // If we can't determine current model, allow the request\n debugLogger.error('AskExpertModel', {\n message: 'Could not determine current model',\n error: e,\n })\n }\n\n // Validate that the model exists and is available\n try {\n const modelManager = getModelManager()\n const modelResolution = modelManager.resolveModelWithInfo(expert_model)\n\n if (!modelResolution.success) {\n const availableModels = modelManager.getAllAvailableModelNames()\n if (availableModels.length > 0) {\n return {\n result: false,\n message: `Model '${expert_model}' is not configured. Available models: ${availableModels.join(', ')}. Check if any available model closely matches the user's request (e.g., 'kimi' matches 'kimi-k2-0711-preview'). If there's a strong match, auto retry using the correct model name. If no close match exists, inform the user that '${expert_model}' needs to be configured using /model command.`,\n }\n } else {\n return {\n result: false,\n message: `Model '${expert_model}' not found and no models are currently configured in the system. Inform the user that models need to be configured first using the /model command.`,\n }\n }\n }\n } catch (error) {\n console.error('Model validation error in AskExpertModelTool:', error)\n logError(error)\n return {\n result: false,\n message: `Failed to validate expert model '${expert_model}'. Please check your model configuration.`,\n }\n }\n\n return { result: true }\n },\n\n renderToolUseMessage(\n { question, expert_model, chat_session_id },\n { verbose },\n ) {\n if (!question || !expert_model) return null\n const isNewSession = chat_session_id === 'new'\n const sessionDisplay = isNewSession\n ? 'new session'\n : `session ${chat_session_id.substring(0, 5)}...`\n const theme = getTheme()\n\n if (verbose) {\n return (\n <Box flexDirection=\"column\">\n <Text bold color=\"yellow\">\n {expert_model}\n </Text>\n <Text color={theme.secondaryText}>{sessionDisplay}</Text>\n <Box marginTop={1}>\n <Text color={theme.text}>\n {question.length > 300\n ? question.substring(0, 300) + '...'\n : question}\n </Text>\n </Box>\n </Box>\n )\n }\n return (\n <Box flexDirection=\"column\">\n <Text bold color=\"yellow\">\n {expert_model}{' '}\n </Text>\n <Text color={theme.secondaryText} dimColor>\n ({sessionDisplay})\n </Text>\n </Box>\n )\n },\n\n renderToolResultMessage(content) {\n const verbose = true // Show more content\n const theme = getTheme()\n\n // Guard against undefined or null content\n if (!content) {\n return (\n <Box flexDirection=\"row\">\n <Text color={theme.secondaryText}>Consultation completed</Text>\n </Box>\n )\n }\n\n if (typeof content === 'object' && content && 'expertAnswer' in content) {\n const expertResult = content as Out\n const isError =\n expertResult.expertAnswer.startsWith('Error') ||\n expertResult.expertAnswer.includes('failed')\n const isInterrupted = expertResult.chatSessionId === 'interrupted'\n\n if (isInterrupted) {\n return (\n <Box flexDirection=\"row\">\n <Text color={theme.secondaryText}>Consultation interrupted</Text>\n </Box>\n )\n }\n\n const answerText = verbose\n ? expertResult.expertAnswer.trim()\n : expertResult.expertAnswer.length > 500\n ? expertResult.expertAnswer.substring(0, 500) + '...'\n : expertResult.expertAnswer.trim()\n\n if (isError) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"red\">{answerText}</Text>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text bold color={theme.text}>\n Response from {expertResult.expertModelName}:\n </Text>\n <Box marginTop={1}>\n <Text color={theme.text}>{applyMarkdown(answerText)}</Text>\n </Box>\n <Box marginTop={1}>\n <Text color={theme.secondaryText} dimColor>\n Session: {expertResult.chatSessionId.substring(0, 8)}\n </Text>\n </Box>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"row\">\n <Text color={theme.secondaryText}>Consultation completed</Text>\n </Box>\n )\n },\n\n renderResultForAssistant(output: Out): string {\n return `[Expert consultation completed]\nExpert Model: ${output.expertModelName}\nSession ID: ${output.chatSessionId}\nTo continue this conversation with context preservation, use this Session ID in your next AskExpertModel call to maintain the full conversation history and context.\n\n${output.expertAnswer}`\n },\n\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n\n async *call(\n { question, expert_model, chat_session_id },\n { abortController, readFileTimestamps },\n ) {\n const expertModel = expert_model\n\n let sessionId: string\n let isInterrupted = false\n\n // Set up abort listener (following TaskTool pattern)\n const abortListener = () => {\n isInterrupted = true\n }\n abortController.signal.addEventListener('abort', abortListener)\n\n try {\n // Initial abort check\n if (abortController.signal.aborted) {\n return yield* this.handleInterrupt()\n }\n // Session management with error handling\n if (chat_session_id === 'new') {\n try {\n const session = createExpertChatSession(expertModel)\n sessionId = session.sessionId\n } catch (error) {\n console.error('Failed to create new expert chat session:', error)\n logError(error)\n throw new Error('Failed to create new chat session')\n }\n } else {\n sessionId = chat_session_id\n try {\n const session = loadExpertChatSession(sessionId)\n if (!session) {\n // Session doesn't exist, create new one\n const newSession = createExpertChatSession(expertModel)\n sessionId = newSession.sessionId\n }\n } catch (error) {\n console.error('Failed to load expert chat session:', error)\n logError(error)\n // Fallback: create new session\n try {\n const newSession = createExpertChatSession(expertModel)\n sessionId = newSession.sessionId\n } catch (createError) {\n console.error(\n 'Failed to create fallback expert chat session:',\n createError,\n )\n logError(createError)\n throw new Error('Unable to create or load chat session')\n }\n }\n }\n\n // Check for cancellation before loading history\n if (isInterrupted || abortController.signal.aborted) {\n return yield* this.handleInterrupt()\n }\n\n // Load history and prepare messages with error handling\n let historyMessages: Array<{ role: string; content: string }>\n try {\n historyMessages = getSessionMessages(sessionId)\n } catch (error) {\n console.error('Failed to load session messages:', error)\n logError(error)\n historyMessages = [] // Fallback to empty history\n }\n\n const messages = [...historyMessages, { role: 'user', content: question }]\n\n let systemMessages\n try {\n systemMessages = messages.map(msg =>\n msg.role === 'user'\n ? createUserMessage(msg.content)\n : createAssistantMessage(msg.content),\n )\n } catch (error) {\n console.error('Failed to create system messages:', error)\n logError(error)\n throw new Error('Failed to prepare conversation messages')\n }\n\n // Check for cancellation before model call\n if (isInterrupted || abortController.signal.aborted) {\n return yield* this.handleInterrupt()\n }\n\n // Yield progress message to show we're connecting\n yield {\n type: 'progress',\n content: createAssistantMessage(\n `Connecting to ${expertModel}... (timeout: 5 minutes)`,\n ),\n }\n\n // Call model with comprehensive error handling and timeout\n let response\n try {\n // Debug: Log the model we're trying to use (using global debug logger)\n const modelManager = getModelManager()\n const modelResolution = modelManager.resolveModelWithInfo(expertModel)\n\n debugLogger.api('EXPERT_MODEL_RESOLUTION', {\n requestedModel: expertModel,\n success: modelResolution.success,\n profileName: modelResolution.profile?.name,\n profileModelName: modelResolution.profile?.modelName,\n provider: modelResolution.profile?.provider,\n isActive: modelResolution.profile?.isActive,\n error: modelResolution.error,\n })\n\n // Create a timeout promise to prevent hanging\n const timeoutMs = 300000 // 300 seconds (5 minutes) timeout for external models\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => {\n reject(\n new Error(\n `Expert model query timed out after ${timeoutMs / 1000}s`,\n ),\n )\n }, timeoutMs)\n })\n\n // Race between the query and timeout\n response = await Promise.race([\n queryLLM(\n systemMessages,\n [], // no system prompt - let expert model use its default behavior\n 0, // no thinking tokens needed\n [], // no tools needed\n abortController.signal,\n {\n safeMode: false,\n model: expertModel,\n prependCLISysprompt: false, // KEY: avoid injecting CLI context\n },\n ),\n timeoutPromise,\n ])\n } catch (error: any) {\n console.error('Expert model query failed:', error)\n logError(error)\n\n // Check for specific error types\n if (\n error.name === 'AbortError' ||\n abortController.signal?.aborted ||\n isInterrupted\n ) {\n return yield* this.handleInterrupt()\n }\n\n if (error.message?.includes('timed out')) {\n throw new Error(\n `Expert model '${expertModel}' timed out after 5 minutes.\\n\\n` +\n `Suggestions:\\n` +\n ` - The model might be experiencing high load\\n` +\n ` - Try a different model or retry later\\n` +\n ` - Consider breaking down your question into smaller parts`,\n )\n }\n\n if (error.message?.includes('rate limit')) {\n throw new Error(\n `Rate limit exceeded for ${expertModel}.\\n\\n` +\n `Please wait a moment and try again, or use a different model.`,\n )\n }\n\n if (error.message?.includes('invalid api key')) {\n throw new Error(\n `Invalid API key for ${expertModel}.\\n\\n` +\n `Please check your model configuration with /model command.`,\n )\n }\n\n if (\n error.message?.includes('model not found') ||\n error.message?.includes('Failed to resolve model')\n ) {\n // Provide helpful model guidance in runtime errors too\n try {\n const modelManager = getModelManager()\n const availableModels = modelManager.getAllAvailableModelNames()\n if (availableModels.length > 0) {\n throw new Error(\n `Model '${expertModel}' is not configured. Available models: ${availableModels.join(', ')}. Check if any available model closely matches the user's request (e.g., 'kimi' matches 'kimi-k2-0711-preview'). If there's a strong match, auto retry using the correct model name. If no close match exists, inform the user that '${expertModel}' needs to be configured using /model command.`,\n )\n } else {\n throw new Error(\n `Model '${expertModel}' not found and no models are currently configured in the system. Inform the user that models need to be configured first using the /model command.`,\n )\n }\n } catch (modelError) {\n // If we can't get model list, fall back to simple error\n throw new Error(\n `Model '${expertModel}' not found. Please check model configuration or inform user about the issue.`,\n )\n }\n }\n\n // Generic fallback\n throw new Error(\n `Expert model query failed: ${error.message || 'Unknown error'}`,\n )\n }\n\n // Extract answer with error handling\n let expertAnswer: string\n try {\n if (!response?.message?.content) {\n throw new Error('No content in expert response')\n }\n\n expertAnswer = response.message.content\n .filter(block => block.type === 'text')\n .map(block => (block as any).text)\n .join('\\n')\n\n if (!expertAnswer.trim()) {\n throw new Error('Expert response was empty')\n }\n } catch (error) {\n console.error('Failed to extract expert answer:', error)\n logError(error)\n throw new Error('Failed to process expert response')\n }\n\n // Save conversation with error handling\n try {\n addMessageToSession(sessionId, 'user', question)\n addMessageToSession(sessionId, 'assistant', expertAnswer)\n } catch (error) {\n console.error('Failed to save conversation to session:', error)\n logError(error)\n // Don't throw here - we got a valid response, saving is non-critical\n }\n\n const result: Out = {\n chatSessionId: sessionId,\n expertModelName: expertModel,\n expertAnswer: expertAnswer,\n }\n\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n } catch (error: any) {\n // Check if error is due to cancellation\n if (\n error.name === 'AbortError' ||\n abortController.signal?.aborted ||\n isInterrupted\n ) {\n return yield* this.handleInterrupt()\n }\n\n console.error('AskExpertModelTool execution failed:', error)\n logError(error)\n\n // Ensure we have a valid sessionId for error response\n const errorSessionId = sessionId || 'error-session'\n\n const errorMessage =\n error.message || 'Expert consultation failed with unknown error'\n const result: Out = {\n chatSessionId: errorSessionId,\n expertModelName: expertModel,\n expertAnswer: `\u274C ${errorMessage}`,\n }\n\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n } finally {\n // Clean up event listener\n abortController.signal.removeEventListener('abort', abortListener)\n }\n },\n\n // Unified interrupt handling method (following TaskTool pattern)\n async *handleInterrupt() {\n yield {\n type: 'result',\n data: {\n chatSessionId: 'interrupted',\n expertModelName: 'cancelled',\n expertAnswer: INTERRUPT_MESSAGE,\n },\n resultForAssistant: INTERRUPT_MESSAGE,\n }\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -64,7 +64,14 @@ ${formattedAnswers}`;
64
64
  return /* @__PURE__ */ React.createElement(FallbackToolUseRejectedMessage, null);
65
65
  },
66
66
  renderToolResultMessage(output) {
67
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: "#10B981" }, " ", "\u23BF "), /* @__PURE__ */ React.createElement(Text, null, "User provided answers")), output.answers.map((answer, index) => /* @__PURE__ */ React.createElement(Box, { key: index, flexDirection: "row", paddingLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { color: "#6B7280" }, "\u2022 "), answer.customInput ? /* @__PURE__ */ React.createElement(Text, null, "Q", answer.questionIndex + 1, ': "', answer.customInput, '"') : answer.selectedOptions ? /* @__PURE__ */ React.createElement(Text, null, "Q", answer.questionIndex + 1, ": Option", " ", answer.selectedOptions.map((i) => i + 1).join(", ")) : /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Q", answer.questionIndex + 1, ": No answer"))));
67
+ if (!output) {
68
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: "#10B981" }, " ", "\u23BF "), /* @__PURE__ */ React.createElement(Text, null, "Question completed")));
69
+ }
70
+ const answers = output.answers || [];
71
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: "#10B981" }, " ", "\u23BF "), /* @__PURE__ */ React.createElement(Text, null, "User provided answers")), answers.map((answer, index) => {
72
+ if (!answer) return null;
73
+ return /* @__PURE__ */ React.createElement(Box, { key: index, flexDirection: "row", paddingLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { color: "#6B7280" }, "\u2022 "), answer.customInput ? /* @__PURE__ */ React.createElement(Text, null, "Q", (answer.questionIndex ?? index) + 1, ': "', answer.customInput, '"') : answer.selectedOptions ? /* @__PURE__ */ React.createElement(Text, null, "Q", (answer.questionIndex ?? index) + 1, ": Option", " ", answer.selectedOptions.map((i) => i + 1).join(", ")) : /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Q", (answer.questionIndex ?? index) + 1, ": No answer"));
74
+ }));
68
75
  },
69
76
  async *call({ questions }, context) {
70
77
  if (!context.askUser) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx"],
4
- "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { Tool, type ExtendedToolUseContext } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport type { UserAnswer } from '@minto-types/askUserQuestion'\n\nconst inputSchema = z.strictObject({\n questions: z\n .array(\n z.object({\n question: z.string().describe('The question to ask the user'),\n header: z\n .string()\n .max(12)\n .optional()\n .describe('Short category label (max 12 chars)'),\n options: z\n .array(\n z.object({\n label: z.string().describe('Option display text'),\n description: z.string().optional().describe('Option explanation'),\n }),\n )\n .min(2)\n .max(4)\n .optional()\n .describe('List of options (2-4 recommended)'),\n multiSelect: z\n .boolean()\n .optional()\n .default(false)\n .describe('Allow multiple selections'),\n }),\n )\n .min(1)\n .max(4)\n .describe('Questions to ask (1-4 questions)'),\n})\n\nexport type AskUserQuestionOutput = {\n answers: UserAnswer[]\n timestamp: number\n}\n\nexport const AskUserQuestionTool = {\n name: 'AskUserQuestion',\n\n async description() {\n return DESCRIPTION\n },\n\n async prompt() {\n return PROMPT\n },\n\n inputSchema,\n\n userFacingName() {\n return 'Ask User Question'\n },\n\n async isEnabled() {\n return true\n },\n\n isReadOnly() {\n return true // Doesn't modify files\n },\n\n isConcurrencySafe() {\n return false // User interaction is not concurrent-safe\n },\n\n needsPermissions() {\n return false // No special permissions needed\n },\n\n renderResultForAssistant(output: AskUserQuestionOutput) {\n const formattedAnswers = output.answers\n .map(answer => {\n if (answer.customInput) {\n return `Q${answer.questionIndex + 1}: \"${answer.customInput}\"`\n }\n if (answer.selectedOptions) {\n return `Q${answer.questionIndex + 1}: Option ${answer.selectedOptions.map(i => i + 1).join(', ')}`\n }\n return `Q${answer.questionIndex + 1}: No answer`\n })\n .join('\\n')\n\n return `User answered:\\n${formattedAnswers}`\n },\n\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const questionCount = input.questions.length\n const questionText =\n questionCount === 1\n ? input.questions[0]!.question\n : `${questionCount} questions`\n return `Asking user: ${questionText}`\n },\n\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n\n renderToolResultMessage(output: AskUserQuestionOutput) {\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box flexDirection=\"row\">\n <Text color=\"#10B981\">{' '}\u23BF </Text>\n <Text>User provided answers</Text>\n </Box>\n {output.answers.map((answer, index) => (\n <Box key={index} flexDirection=\"row\" paddingLeft={4}>\n <Text color=\"#6B7280\">\u2022 </Text>\n {answer.customInput ? (\n <Text>\n Q{answer.questionIndex + 1}: \"{answer.customInput}\"\n </Text>\n ) : answer.selectedOptions ? (\n <Text>\n Q{answer.questionIndex + 1}: Option{' '}\n {answer.selectedOptions.map(i => i + 1).join(', ')}\n </Text>\n ) : (\n <Text dimColor>Q{answer.questionIndex + 1}: No answer</Text>\n )}\n </Box>\n ))}\n </Box>\n )\n },\n\n async *call(\n { questions }: z.infer<typeof inputSchema>,\n context: ExtendedToolUseContext,\n ) {\n // Check if askUser function is available\n if (!context.askUser) {\n throw new Error(\n 'AskUserQuestion tool requires askUser function in context',\n )\n }\n\n try {\n // Convert parsed questions to UserQuestion type\n const userQuestions = questions.map(q => ({\n question: q.question,\n header: q.header,\n options: q.options?.map(opt => ({\n label: opt.label,\n description: opt.description,\n })),\n multiSelect: q.multiSelect ?? false,\n }))\n\n // Call askUser and wait for user response\n const answers = await context.askUser(userQuestions)\n\n // Return the result\n yield {\n type: 'result',\n data: {\n answers,\n timestamp: Date.now(),\n },\n resultForAssistant: `User answered:\\n${answers\n .map(answer => {\n if (answer.customInput) {\n return `Q${answer.questionIndex + 1}: \"${answer.customInput}\"`\n }\n if (answer.selectedOptions) {\n return `Q${answer.questionIndex + 1}: Option ${answer.selectedOptions.map(i => i + 1).join(', ')}`\n }\n return `Q${answer.questionIndex + 1}: No answer`\n })\n .join('\\n')}`,\n }\n } catch (error) {\n // User cancelled or error occurred\n throw new Error(\n `Failed to get user response: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n },\n} satisfies Tool<typeof inputSchema, AskUserQuestionOutput>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { Tool, type ExtendedToolUseContext } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport type { UserAnswer } from '@minto-types/askUserQuestion'\n\nconst inputSchema = z.strictObject({\n questions: z\n .array(\n z.object({\n question: z.string().describe('The question to ask the user'),\n header: z\n .string()\n .max(12)\n .optional()\n .describe('Short category label (max 12 chars)'),\n options: z\n .array(\n z.object({\n label: z.string().describe('Option display text'),\n description: z.string().optional().describe('Option explanation'),\n }),\n )\n .min(2)\n .max(4)\n .optional()\n .describe('List of options (2-4 recommended)'),\n multiSelect: z\n .boolean()\n .optional()\n .default(false)\n .describe('Allow multiple selections'),\n }),\n )\n .min(1)\n .max(4)\n .describe('Questions to ask (1-4 questions)'),\n})\n\nexport type AskUserQuestionOutput = {\n answers: UserAnswer[]\n timestamp: number\n}\n\nexport const AskUserQuestionTool = {\n name: 'AskUserQuestion',\n\n async description() {\n return DESCRIPTION\n },\n\n async prompt() {\n return PROMPT\n },\n\n inputSchema,\n\n userFacingName() {\n return 'Ask User Question'\n },\n\n async isEnabled() {\n return true\n },\n\n isReadOnly() {\n return true // Doesn't modify files\n },\n\n isConcurrencySafe() {\n return false // User interaction is not concurrent-safe\n },\n\n needsPermissions() {\n return false // No special permissions needed\n },\n\n renderResultForAssistant(output: AskUserQuestionOutput) {\n const formattedAnswers = output.answers\n .map(answer => {\n if (answer.customInput) {\n return `Q${answer.questionIndex + 1}: \"${answer.customInput}\"`\n }\n if (answer.selectedOptions) {\n return `Q${answer.questionIndex + 1}: Option ${answer.selectedOptions.map(i => i + 1).join(', ')}`\n }\n return `Q${answer.questionIndex + 1}: No answer`\n })\n .join('\\n')\n\n return `User answered:\\n${formattedAnswers}`\n },\n\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const questionCount = input.questions.length\n const questionText =\n questionCount === 1\n ? input.questions[0]!.question\n : `${questionCount} questions`\n return `Asking user: ${questionText}`\n },\n\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n\n renderToolResultMessage(output: AskUserQuestionOutput) {\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box flexDirection=\"row\">\n <Text color=\"#10B981\">{' '}\u23BF </Text>\n <Text>Question completed</Text>\n </Box>\n </Box>\n )\n }\n\n const answers = output.answers || []\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box flexDirection=\"row\">\n <Text color=\"#10B981\">{' '}\u23BF </Text>\n <Text>User provided answers</Text>\n </Box>\n {answers.map((answer, index) => {\n // Guard against null/undefined answers\n if (!answer) return null\n return (\n <Box key={index} flexDirection=\"row\" paddingLeft={4}>\n <Text color=\"#6B7280\">\u2022 </Text>\n {answer.customInput ? (\n <Text>\n Q{(answer.questionIndex ?? index) + 1}: \"{answer.customInput}\"\n </Text>\n ) : answer.selectedOptions ? (\n <Text>\n Q{(answer.questionIndex ?? index) + 1}: Option{' '}\n {answer.selectedOptions.map(i => i + 1).join(', ')}\n </Text>\n ) : (\n <Text dimColor>\n Q{(answer.questionIndex ?? index) + 1}: No answer\n </Text>\n )}\n </Box>\n )\n })}\n </Box>\n )\n },\n\n async *call(\n { questions }: z.infer<typeof inputSchema>,\n context: ExtendedToolUseContext,\n ) {\n // Check if askUser function is available\n if (!context.askUser) {\n throw new Error(\n 'AskUserQuestion tool requires askUser function in context',\n )\n }\n\n try {\n // Convert parsed questions to UserQuestion type\n const userQuestions = questions.map(q => ({\n question: q.question,\n header: q.header,\n options: q.options?.map(opt => ({\n label: opt.label,\n description: opt.description,\n })),\n multiSelect: q.multiSelect ?? false,\n }))\n\n // Call askUser and wait for user response\n const answers = await context.askUser(userQuestions)\n\n // Return the result\n yield {\n type: 'result',\n data: {\n answers,\n timestamp: Date.now(),\n },\n resultForAssistant: `User answered:\\n${answers\n .map(answer => {\n if (answer.customInput) {\n return `Q${answer.questionIndex + 1}: \"${answer.customInput}\"`\n }\n if (answer.selectedOptions) {\n return `Q${answer.questionIndex + 1}: Option ${answer.selectedOptions.map(i => i + 1).join(', ')}`\n }\n return `Q${answer.questionIndex + 1}: No answer`\n })\n .join('\\n')}`,\n }\n } catch (error) {\n // User cancelled or error occurred\n throw new Error(\n `Failed to get user response: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n },\n} satisfies Tool<typeof inputSchema, AskUserQuestionOutput>\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,72 @@
1
+ import { logError } from "../utils/log.js";
2
+ class BaseTool {
3
+ /** Tool name for identification and error messages */
4
+ toolName;
5
+ /** Whether to log errors (default: true) */
6
+ logErrors;
7
+ constructor(config) {
8
+ this.toolName = config.name;
9
+ this.logErrors = config.logErrors ?? true;
10
+ }
11
+ /**
12
+ * Wrapped call method with automatic error handling.
13
+ *
14
+ * This method:
15
+ * 1. Tracks whether a result has been yielded
16
+ * 2. Wraps execute() in try-catch-finally
17
+ * 3. Ensures a result is always yielded
18
+ * 4. Calls cleanup() in finally block
19
+ *
20
+ * DO NOT override this method - implement execute() instead.
21
+ */
22
+ async *call(input, context) {
23
+ let hasYieldedResult = false;
24
+ try {
25
+ for await (const result of this.execute(input, context)) {
26
+ if (result.type === "result") {
27
+ hasYieldedResult = true;
28
+ }
29
+ yield result;
30
+ }
31
+ } catch (error) {
32
+ const errorMessage = error instanceof Error ? error.message : String(error);
33
+ if (this.logErrors) {
34
+ logError(`${this.toolName} error: ${errorMessage}`);
35
+ }
36
+ yield {
37
+ type: "result",
38
+ data: this.createErrorResult(errorMessage),
39
+ resultForAssistant: `${this.toolName} failed: ${errorMessage}`
40
+ };
41
+ hasYieldedResult = true;
42
+ } finally {
43
+ if (this.cleanup) {
44
+ try {
45
+ await this.cleanup(context);
46
+ } catch (cleanupError) {
47
+ if (this.logErrors) {
48
+ logError(`${this.toolName} cleanup error: ${cleanupError}`);
49
+ }
50
+ }
51
+ }
52
+ if (!hasYieldedResult) {
53
+ yield {
54
+ type: "result",
55
+ data: this.createErrorResult("Tool terminated unexpectedly"),
56
+ resultForAssistant: `${this.toolName} terminated unexpectedly`
57
+ };
58
+ }
59
+ }
60
+ }
61
+ }
62
+ function createToolFromBase(baseTool, toolDefinition) {
63
+ return {
64
+ ...toolDefinition,
65
+ call: (input, context) => baseTool.call(input, context)
66
+ };
67
+ }
68
+ export {
69
+ BaseTool,
70
+ createToolFromBase
71
+ };
72
+ //# sourceMappingURL=BaseTool.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/tools/BaseTool.ts"],
4
+ "sourcesContent": ["/**\n * BaseTool - Abstract base class for tools with unified error handling\n *\n * This class provides a standardized pattern for tool implementations:\n * - Automatic try-catch-finally wrapping\n * - Guaranteed result yielding even on errors\n * - Optional cleanup hook for resource management\n * - Consistent error message formatting\n *\n * Tools that extend this class should implement:\n * - execute(): The core tool logic (generator function)\n * - createErrorResult(): Create error result in the tool's output format\n * - Optionally cleanup(): Resource cleanup logic\n *\n * @module tools/BaseTool\n */\n\nimport { z } from 'zod'\nimport type { Tool, ToolUseContext, ValidationResult } from '@tool'\nimport { logError } from '@utils/log'\n\n/**\n * Result type that tools yield during execution\n */\nexport type ToolResult<TOutput> =\n | {\n type: 'result'\n data: TOutput\n resultForAssistant?: string | any[]\n newMessages?: unknown[]\n }\n | {\n type: 'progress'\n content: any\n normalizedMessages?: any[]\n tools?: any[]\n }\n\n/**\n * Configuration options for BaseTool\n */\nexport interface BaseToolConfig {\n /** Tool name used for identification */\n name: string\n /** Whether errors should be logged (default: true) */\n logErrors?: boolean\n}\n\n/**\n * Abstract base class that provides unified error handling for tools.\n *\n * By extending this class, tools automatically get:\n * 1. try-catch-finally wrapping around the execute() method\n * 2. Guaranteed result yielding - even if execute() throws or doesn't yield\n * 3. Automatic error logging\n * 4. Cleanup hook for resource management\n *\n * @example\n * ```typescript\n * class MyTool extends BaseTool<MyInputSchema, MyOutput> {\n * protected async *execute(input, context): AsyncGenerator<ToolResult<MyOutput>> {\n * // Tool implementation\n * yield { type: 'result', data: result }\n * }\n *\n * protected createErrorResult(errorMessage: string): MyOutput {\n * return { error: errorMessage }\n * }\n * }\n * ```\n */\nexport abstract class BaseTool<TInput extends z.ZodObject<any>, TOutput> {\n /** Tool name for identification and error messages */\n protected readonly toolName: string\n\n /** Whether to log errors (default: true) */\n protected readonly logErrors: boolean\n\n constructor(config: BaseToolConfig) {\n this.toolName = config.name\n this.logErrors = config.logErrors ?? true\n }\n\n /**\n * Core execution logic - implement this in subclasses.\n *\n * This method should:\n * - Yield progress updates as needed\n * - Yield exactly one result at the end\n * - Let errors propagate (they'll be caught by call())\n *\n * @param input - Validated tool input\n * @param context - Tool execution context\n */\n protected abstract execute(\n input: z.infer<TInput>,\n context: ToolUseContext,\n ): AsyncGenerator<ToolResult<TOutput>, void, unknown>\n\n /**\n * Create an error result in the tool's output format.\n *\n * This is called when execute() throws or when cleanup is needed.\n *\n * @param errorMessage - Human-readable error message\n */\n protected abstract createErrorResult(errorMessage: string): TOutput\n\n /**\n * Optional cleanup logic - override in subclasses if needed.\n *\n * This is called in the finally block, regardless of success or failure.\n * Use this for:\n * - Releasing resources\n * - Cancelling pending operations\n * - Resetting state\n *\n * @param context - Tool execution context\n */\n protected async cleanup?(context: ToolUseContext): Promise<void>\n\n /**\n * Wrapped call method with automatic error handling.\n *\n * This method:\n * 1. Tracks whether a result has been yielded\n * 2. Wraps execute() in try-catch-finally\n * 3. Ensures a result is always yielded\n * 4. Calls cleanup() in finally block\n *\n * DO NOT override this method - implement execute() instead.\n */\n async *call(\n input: z.infer<TInput>,\n context: ToolUseContext,\n ): AsyncGenerator<ToolResult<TOutput>, void, unknown> {\n let hasYieldedResult = false\n\n try {\n for await (const result of this.execute(input, context)) {\n if (result.type === 'result') {\n hasYieldedResult = true\n }\n yield result\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error)\n\n if (this.logErrors) {\n logError(`${this.toolName} error: ${errorMessage}`)\n }\n\n // Yield error result\n yield {\n type: 'result',\n data: this.createErrorResult(errorMessage),\n resultForAssistant: `${this.toolName} failed: ${errorMessage}`,\n }\n hasYieldedResult = true\n } finally {\n // Run cleanup if defined\n if (this.cleanup) {\n try {\n await this.cleanup(context)\n } catch (cleanupError) {\n if (this.logErrors) {\n logError(`${this.toolName} cleanup error: ${cleanupError}`)\n }\n }\n }\n\n // Safety net: ensure we always yield a result\n if (!hasYieldedResult) {\n yield {\n type: 'result',\n data: this.createErrorResult('Tool terminated unexpectedly'),\n resultForAssistant: `${this.toolName} terminated unexpectedly`,\n }\n }\n }\n }\n}\n\n/**\n * Helper function to create a tool from BaseTool instance.\n *\n * This adapts a BaseTool class instance to the Tool interface\n * expected by the tool system.\n *\n * @param baseTool - Instance of a BaseTool subclass\n * @param toolDefinition - Additional tool properties (schema, render methods, etc.)\n */\nexport function createToolFromBase<TInput extends z.ZodObject<any>, TOutput>(\n baseTool: BaseTool<TInput, TOutput>,\n toolDefinition: Omit<Tool<TInput, TOutput>, 'call'>,\n): Tool<TInput, TOutput> {\n return {\n ...toolDefinition,\n call: (input, context) => baseTool.call(input, context),\n }\n}\n"],
5
+ "mappings": "AAmBA,SAAS,gBAAgB;AAoDlB,MAAe,SAAmD;AAAA;AAAA,EAEpD;AAAA;AAAA,EAGA;AAAA,EAEnB,YAAY,QAAwB;AAClC,SAAK,WAAW,OAAO;AACvB,SAAK,YAAY,OAAO,aAAa;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmDA,OAAO,KACL,OACA,SACoD;AACpD,QAAI,mBAAmB;AAEvB,QAAI;AACF,uBAAiB,UAAU,KAAK,QAAQ,OAAO,OAAO,GAAG;AACvD,YAAI,OAAO,SAAS,UAAU;AAC5B,6BAAmB;AAAA,QACrB;AACA,cAAM;AAAA,MACR;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eACJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAEvD,UAAI,KAAK,WAAW;AAClB,iBAAS,GAAG,KAAK,QAAQ,WAAW,YAAY,EAAE;AAAA,MACpD;AAGA,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,MAAM,KAAK,kBAAkB,YAAY;AAAA,QACzC,oBAAoB,GAAG,KAAK,QAAQ,YAAY,YAAY;AAAA,MAC9D;AACA,yBAAmB;AAAA,IACrB,UAAE;AAEA,UAAI,KAAK,SAAS;AAChB,YAAI;AACF,gBAAM,KAAK,QAAQ,OAAO;AAAA,QAC5B,SAAS,cAAc;AACrB,cAAI,KAAK,WAAW;AAClB,qBAAS,GAAG,KAAK,QAAQ,mBAAmB,YAAY,EAAE;AAAA,UAC5D;AAAA,QACF;AAAA,MACF;AAGA,UAAI,CAAC,kBAAkB;AACrB,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,MAAM,KAAK,kBAAkB,8BAA8B;AAAA,UAC3D,oBAAoB,GAAG,KAAK,QAAQ;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAWO,SAAS,mBACd,UACA,gBACuB;AACvB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK,OAAO,OAAO;AAAA,EACxD;AACF;",
6
+ "names": []
7
+ }
@@ -3,6 +3,9 @@ import * as React from "react";
3
3
  import { getTheme } from "../../utils/theme.js";
4
4
  function BashOutputToolResultMessage({ content }) {
5
5
  const theme = getTheme();
6
+ if (!content) {
7
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Status: "), /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, "unknown")));
8
+ }
6
9
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Status: "), /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, content.status)), content.stdout && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Standard Output:"), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, content.stdout))), content.stderr && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Standard Error:"), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.error }, content.stderr))), content.hasMore && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.warning }, "(Output truncated - more output available)")), !content.stdout && !content.stderr && content.status === "running" && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "(No new output)")));
7
10
  }
8
11
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/BashOutputTool/BashOutputToolResultMessage.tsx"],
4
- "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport type { Out } from './BashOutputTool'\nimport { getTheme } from '@utils/theme'\n\nexport function BashOutputToolResultMessage({ content }: { content: Out }) {\n const theme = getTheme()\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box>\n <Text color={theme.secondaryText}>Status: </Text>\n <Text color={theme.primary}>{content.status}</Text>\n </Box>\n\n {content.stdout && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.secondaryText}>Standard Output:</Text>\n <Box paddingLeft={2}>\n <Text color={theme.primary}>{content.stdout}</Text>\n </Box>\n </Box>\n )}\n\n {content.stderr && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.error}>Standard Error:</Text>\n <Box paddingLeft={2}>\n <Text color={theme.error}>{content.stderr}</Text>\n </Box>\n </Box>\n )}\n\n {content.hasMore && (\n <Box marginTop={1}>\n <Text color={theme.warning}>\n (Output truncated - more output available)\n </Text>\n </Box>\n )}\n\n {!content.stdout && !content.stderr && content.status === 'running' && (\n <Box marginTop={1}>\n <Text color={theme.secondaryText}>(No new output)</Text>\n </Box>\n )}\n </Box>\n )\n}\n"],
5
- "mappings": "AAAA,SAAS,KAAK,YAAY;AAC1B,YAAY,WAAW;AAEvB,SAAS,gBAAgB;AAElB,SAAS,4BAA4B,EAAE,QAAQ,GAAqB;AACzE,QAAM,QAAQ,SAAS;AAEvB,SACE,oCAAC,OAAI,eAAc,UAAS,aAAa,KACvC,oCAAC,WACC,oCAAC,QAAK,OAAO,MAAM,iBAAe,UAAQ,GAC1C,oCAAC,QAAK,OAAO,MAAM,WAAU,QAAQ,MAAO,CAC9C,GAEC,QAAQ,UACP,oCAAC,OAAI,eAAc,UAAS,WAAW,KACrC,oCAAC,QAAK,OAAO,MAAM,iBAAe,kBAAgB,GAClD,oCAAC,OAAI,aAAa,KAChB,oCAAC,QAAK,OAAO,MAAM,WAAU,QAAQ,MAAO,CAC9C,CACF,GAGD,QAAQ,UACP,oCAAC,OAAI,eAAc,UAAS,WAAW,KACrC,oCAAC,QAAK,OAAO,MAAM,SAAO,iBAAe,GACzC,oCAAC,OAAI,aAAa,KAChB,oCAAC,QAAK,OAAO,MAAM,SAAQ,QAAQ,MAAO,CAC5C,CACF,GAGD,QAAQ,WACP,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,OAAO,MAAM,WAAS,4CAE5B,CACF,GAGD,CAAC,QAAQ,UAAU,CAAC,QAAQ,UAAU,QAAQ,WAAW,aACxD,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,OAAO,MAAM,iBAAe,iBAAe,CACnD,CAEJ;AAEJ;",
4
+ "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport type { Out } from './BashOutputTool'\nimport { getTheme } from '@utils/theme'\n\nexport function BashOutputToolResultMessage({ content }: { content: Out }) {\n const theme = getTheme()\n\n // Guard against undefined or null content\n if (!content) {\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box>\n <Text color={theme.secondaryText}>Status: </Text>\n <Text color={theme.primary}>unknown</Text>\n </Box>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box>\n <Text color={theme.secondaryText}>Status: </Text>\n <Text color={theme.primary}>{content.status}</Text>\n </Box>\n\n {content.stdout && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.secondaryText}>Standard Output:</Text>\n <Box paddingLeft={2}>\n <Text color={theme.primary}>{content.stdout}</Text>\n </Box>\n </Box>\n )}\n\n {content.stderr && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.error}>Standard Error:</Text>\n <Box paddingLeft={2}>\n <Text color={theme.error}>{content.stderr}</Text>\n </Box>\n </Box>\n )}\n\n {content.hasMore && (\n <Box marginTop={1}>\n <Text color={theme.warning}>\n (Output truncated - more output available)\n </Text>\n </Box>\n )}\n\n {!content.stdout && !content.stderr && content.status === 'running' && (\n <Box marginTop={1}>\n <Text color={theme.secondaryText}>(No new output)</Text>\n </Box>\n )}\n </Box>\n )\n}\n"],
5
+ "mappings": "AAAA,SAAS,KAAK,YAAY;AAC1B,YAAY,WAAW;AAEvB,SAAS,gBAAgB;AAElB,SAAS,4BAA4B,EAAE,QAAQ,GAAqB;AACzE,QAAM,QAAQ,SAAS;AAGvB,MAAI,CAAC,SAAS;AACZ,WACE,oCAAC,OAAI,eAAc,UAAS,aAAa,KACvC,oCAAC,WACC,oCAAC,QAAK,OAAO,MAAM,iBAAe,UAAQ,GAC1C,oCAAC,QAAK,OAAO,MAAM,WAAS,SAAO,CACrC,CACF;AAAA,EAEJ;AAEA,SACE,oCAAC,OAAI,eAAc,UAAS,aAAa,KACvC,oCAAC,WACC,oCAAC,QAAK,OAAO,MAAM,iBAAe,UAAQ,GAC1C,oCAAC,QAAK,OAAO,MAAM,WAAU,QAAQ,MAAO,CAC9C,GAEC,QAAQ,UACP,oCAAC,OAAI,eAAc,UAAS,WAAW,KACrC,oCAAC,QAAK,OAAO,MAAM,iBAAe,kBAAgB,GAClD,oCAAC,OAAI,aAAa,KAChB,oCAAC,QAAK,OAAO,MAAM,WAAU,QAAQ,MAAO,CAC9C,CACF,GAGD,QAAQ,UACP,oCAAC,OAAI,eAAc,UAAS,WAAW,KACrC,oCAAC,QAAK,OAAO,MAAM,SAAO,iBAAe,GACzC,oCAAC,OAAI,aAAa,KAChB,oCAAC,QAAK,OAAO,MAAM,SAAQ,QAAQ,MAAO,CAC5C,CACF,GAGD,QAAQ,WACP,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,OAAO,MAAM,WAAS,4CAE5B,CACF,GAGD,CAAC,QAAQ,UAAU,CAAC,QAAQ,UAAU,QAAQ,WAAW,aACxD,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,OAAO,MAAM,iBAAe,iBAAe,CACnD,CAEJ;AAEJ;",
6
6
  "names": []
7
7
  }