@within-7/minto 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/dist/commands/agents/AgentsCommand.js +2342 -0
  2. package/dist/commands/agents/AgentsCommand.js.map +7 -0
  3. package/dist/commands/agents/constants.js +58 -0
  4. package/dist/commands/agents/constants.js.map +7 -0
  5. package/dist/commands/agents/index.js +37 -0
  6. package/dist/commands/agents/index.js.map +7 -0
  7. package/dist/commands/agents/types.js +10 -0
  8. package/dist/commands/agents/types.js.map +7 -0
  9. package/dist/commands/agents/utils/fileOperations.js +185 -0
  10. package/dist/commands/agents/utils/fileOperations.js.map +7 -0
  11. package/dist/commands/agents/utils/index.js +21 -0
  12. package/dist/commands/agents/utils/index.js.map +7 -0
  13. package/dist/commands/bug.js +2 -2
  14. package/dist/commands/bug.js.map +2 -2
  15. package/dist/commands/compact.js +5 -5
  16. package/dist/commands/compact.js.map +2 -2
  17. package/dist/commands/ctx_viz.js +55 -22
  18. package/dist/commands/ctx_viz.js.map +2 -2
  19. package/dist/commands/mcp-interactive.js +11 -11
  20. package/dist/commands/mcp-interactive.js.map +2 -2
  21. package/dist/commands/model.js +94 -32
  22. package/dist/commands/model.js.map +3 -3
  23. package/dist/commands/plugin/AddMarketplaceForm.js +49 -21
  24. package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
  25. package/dist/commands/plugin/ConfirmDialog.js +38 -26
  26. package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
  27. package/dist/commands/plugin/InstalledPluginsByMarketplace.js +24 -8
  28. package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
  29. package/dist/commands/plugin/InstalledPluginsManager.js +3 -1
  30. package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
  31. package/dist/commands/plugin/MainMenu.js +16 -7
  32. package/dist/commands/plugin/MainMenu.js.map +2 -2
  33. package/dist/commands/plugin/MarketplaceManager.js +84 -39
  34. package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
  35. package/dist/commands/plugin/MarketplaceSelector.js +7 -3
  36. package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
  37. package/dist/commands/plugin/PlaceholderScreen.js +16 -2
  38. package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
  39. package/dist/commands/plugin/PluginBrowser.js +4 -2
  40. package/dist/commands/plugin/PluginBrowser.js.map +2 -2
  41. package/dist/commands/plugin/PluginDetailsInstall.js +12 -6
  42. package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
  43. package/dist/commands/plugin/PluginDetailsManage.js +14 -5
  44. package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
  45. package/dist/commands/plugin/example-usage.js.map +2 -2
  46. package/dist/commands/plugin/utils.js.map +2 -2
  47. package/dist/commands/plugin.js +226 -46
  48. package/dist/commands/plugin.js.map +2 -2
  49. package/dist/commands/refreshCommands.js +6 -3
  50. package/dist/commands/refreshCommands.js.map +2 -2
  51. package/dist/commands/resume.js +2 -1
  52. package/dist/commands/resume.js.map +2 -2
  53. package/dist/commands/setup.js +19 -5
  54. package/dist/commands/setup.js.map +2 -2
  55. package/dist/commands/terminalSetup.js +2 -2
  56. package/dist/commands/terminalSetup.js.map +1 -1
  57. package/dist/commands.js +14 -30
  58. package/dist/commands.js.map +2 -2
  59. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
  60. package/dist/components/AskUserQuestionDialog/QuestionView.js +10 -1
  61. package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
  62. package/dist/components/BackgroundTasksPanel.js +5 -1
  63. package/dist/components/BackgroundTasksPanel.js.map +2 -2
  64. package/dist/components/Config.js +17 -4
  65. package/dist/components/Config.js.map +2 -2
  66. package/dist/components/ConsoleOAuthFlow.js.map +2 -2
  67. package/dist/components/CustomSelect/select-option.js +4 -1
  68. package/dist/components/CustomSelect/select-option.js.map +2 -2
  69. package/dist/components/Help.js +6 -8
  70. package/dist/components/Help.js.map +2 -2
  71. package/dist/components/Logo.js +1 -1
  72. package/dist/components/Logo.js.map +2 -2
  73. package/dist/components/ModelListManager.js.map +2 -2
  74. package/dist/components/ModelSelector/ModelSelector.js +2030 -0
  75. package/dist/components/ModelSelector/ModelSelector.js.map +7 -0
  76. package/dist/components/ModelSelector/ScreenContainer.js +27 -0
  77. package/dist/components/ModelSelector/ScreenContainer.js.map +7 -0
  78. package/dist/components/ModelSelector/constants.js +37 -0
  79. package/dist/components/ModelSelector/constants.js.map +7 -0
  80. package/dist/components/ModelSelector/hooks/index.js +5 -0
  81. package/dist/components/ModelSelector/hooks/index.js.map +7 -0
  82. package/dist/components/ModelSelector/hooks/useEscapeNavigation.js +21 -0
  83. package/dist/components/ModelSelector/hooks/useEscapeNavigation.js.map +7 -0
  84. package/dist/components/ModelSelector/index.js +17 -0
  85. package/dist/components/ModelSelector/index.js.map +7 -0
  86. package/dist/components/ModelSelector/types.js +1 -0
  87. package/dist/components/ModelSelector/types.js.map +7 -0
  88. package/dist/components/PressEnterToContinue.js +1 -1
  89. package/dist/components/PressEnterToContinue.js.map +2 -2
  90. package/dist/components/ProjectOnboarding.js +1 -1
  91. package/dist/components/ProjectOnboarding.js.map +2 -2
  92. package/dist/components/PromptInput.js +88 -37
  93. package/dist/components/PromptInput.js.map +2 -2
  94. package/dist/components/QuitSummary.js +17 -10
  95. package/dist/components/QuitSummary.js.map +2 -2
  96. package/dist/components/SentryErrorBoundary.js.map +2 -2
  97. package/dist/components/StreamingBashOutput.js.map +2 -2
  98. package/dist/components/StructuredDiff.js.map +2 -2
  99. package/dist/components/SubagentProgress.js.map +2 -2
  100. package/dist/components/TaskCard.js.map +2 -2
  101. package/dist/components/TextInput.js.map +1 -1
  102. package/dist/components/TodoItem.js.map +1 -1
  103. package/dist/components/binary-feedback/BinaryFeedbackOption.js +1 -3
  104. package/dist/components/binary-feedback/BinaryFeedbackOption.js.map +2 -2
  105. package/dist/components/messages/AssistantLocalCommandOutputMessage.js.map +1 -1
  106. package/dist/components/messages/AssistantToolUseMessage.js +3 -1
  107. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  108. package/dist/components/messages/TaskProgressMessage.js.map +2 -2
  109. package/dist/components/messages/TaskToolMessage.js.map +2 -2
  110. package/dist/components/messages/UserToolResultMessage/utils.js.map +2 -2
  111. package/dist/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js.map +2 -2
  112. package/dist/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js.map +2 -2
  113. package/dist/components/permissions/hooks.js.map +2 -2
  114. package/dist/constants/modelCapabilities.js +1 -1
  115. package/dist/constants/modelCapabilities.js.map +2 -2
  116. package/dist/constants/prompts.js.map +1 -1
  117. package/dist/constants/timing.js +34 -0
  118. package/dist/constants/timing.js.map +7 -0
  119. package/dist/entrypoints/cli.js +128 -33
  120. package/dist/entrypoints/cli.js.map +3 -3
  121. package/dist/entrypoints/mcp.js +13 -18
  122. package/dist/entrypoints/mcp.js.map +2 -2
  123. package/dist/hooks/useCanUseTool.js.map +2 -2
  124. package/dist/hooks/useCancelRequest.js.map +1 -1
  125. package/dist/hooks/useHistorySearch.js.map +2 -2
  126. package/dist/hooks/useLogStartupTime.js.map +2 -2
  127. package/dist/hooks/usePermissionRequestLogging.js.map +2 -2
  128. package/dist/hooks/useTextInput.js.map +1 -1
  129. package/dist/hooks/useUnifiedCompletion.js +493 -394
  130. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  131. package/dist/index.js.map +2 -2
  132. package/dist/permissions.js +4 -7
  133. package/dist/permissions.js.map +2 -2
  134. package/dist/query.js +6 -1
  135. package/dist/query.js.map +2 -2
  136. package/dist/screens/REPL.js +72 -36
  137. package/dist/screens/REPL.js.map +2 -2
  138. package/dist/screens/ResumeConversation.js +2 -1
  139. package/dist/screens/ResumeConversation.js.map +2 -2
  140. package/dist/services/adapters/base.js.map +2 -2
  141. package/dist/services/adapters/chatCompletions.js.map +2 -2
  142. package/dist/services/adapters/responsesAPI.js +3 -1
  143. package/dist/services/adapters/responsesAPI.js.map +2 -2
  144. package/dist/services/claude.js +327 -328
  145. package/dist/services/claude.js.map +2 -2
  146. package/dist/services/customCommands.js +6 -1
  147. package/dist/services/customCommands.js.map +2 -2
  148. package/dist/services/fileFreshness.js.map +2 -2
  149. package/dist/services/gpt5ConnectionTest.js +20 -7
  150. package/dist/services/gpt5ConnectionTest.js.map +2 -2
  151. package/dist/services/hookExecutor.js +6 -12
  152. package/dist/services/hookExecutor.js.map +2 -2
  153. package/dist/services/mcpClient.js +29 -2
  154. package/dist/services/mcpClient.js.map +2 -2
  155. package/dist/services/mentionProcessor.js +23 -10
  156. package/dist/services/mentionProcessor.js.map +2 -2
  157. package/dist/services/modelAdapterFactory.js.map +2 -2
  158. package/dist/services/oauth.js.map +2 -2
  159. package/dist/services/openai.js +109 -72
  160. package/dist/services/openai.js.map +3 -3
  161. package/dist/services/responseStateManager.js.map +2 -2
  162. package/dist/services/systemReminder.js.map +2 -2
  163. package/dist/tools/ArchitectTool/ArchitectTool.js +10 -9
  164. package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
  165. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +14 -8
  166. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  167. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +8 -1
  168. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
  169. package/dist/tools/BashOutputTool/BashOutputTool.js.map +2 -2
  170. package/dist/tools/BashTool/BashTool.js.map +2 -2
  171. package/dist/tools/FileReadTool/FileReadTool.js +23 -4
  172. package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
  173. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  174. package/dist/tools/GlobTool/GlobTool.js +11 -2
  175. package/dist/tools/GlobTool/GlobTool.js.map +2 -2
  176. package/dist/tools/GrepTool/GrepTool.js +7 -5
  177. package/dist/tools/GrepTool/GrepTool.js.map +2 -2
  178. package/dist/tools/MCPTool/MCPTool.js +11 -12
  179. package/dist/tools/MCPTool/MCPTool.js.map +2 -2
  180. package/dist/tools/MultiEditTool/MultiEditTool.js +4 -1
  181. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  182. package/dist/tools/NotebookReadTool/NotebookReadTool.js +11 -5
  183. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
  184. package/dist/tools/SkillTool/SkillTool.js +18 -6
  185. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  186. package/dist/tools/TaskTool/TaskTool.js +37 -51
  187. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  188. package/dist/tools/TaskTool/prompt.js.map +2 -2
  189. package/dist/tools/ThinkTool/ThinkTool.js +6 -1
  190. package/dist/tools/ThinkTool/ThinkTool.js.map +2 -2
  191. package/dist/tools/TodoWriteTool/TodoWriteTool.js +29 -5
  192. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
  193. package/dist/tools/URLFetcherTool/URLFetcherTool.js +5 -2
  194. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
  195. package/dist/tools/URLFetcherTool/cache.js +6 -3
  196. package/dist/tools/URLFetcherTool/cache.js.map +2 -2
  197. package/dist/tools/URLFetcherTool/htmlToMarkdown.js +3 -1
  198. package/dist/tools/URLFetcherTool/htmlToMarkdown.js.map +2 -2
  199. package/dist/tools/WebSearchTool/WebSearchTool.js +6 -1
  200. package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
  201. package/dist/tools/WebSearchTool/prompt.js.map +2 -2
  202. package/dist/tools/WebSearchTool/searchProviders.js +15 -6
  203. package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
  204. package/dist/tools.js +4 -1
  205. package/dist/tools.js.map +2 -2
  206. package/dist/types/core.js +1 -0
  207. package/dist/types/core.js.map +7 -0
  208. package/dist/types/hooks.js +1 -4
  209. package/dist/types/hooks.js.map +2 -2
  210. package/dist/types/marketplace.js +8 -2
  211. package/dist/types/marketplace.js.map +2 -2
  212. package/dist/types/plugin.js +9 -6
  213. package/dist/types/plugin.js.map +2 -2
  214. package/dist/utils/BackgroundShellManager.js +76 -10
  215. package/dist/utils/BackgroundShellManager.js.map +2 -2
  216. package/dist/utils/PersistentShell.js +7 -2
  217. package/dist/utils/PersistentShell.js.map +2 -2
  218. package/dist/utils/advancedFuzzyMatcher.js +4 -1
  219. package/dist/utils/advancedFuzzyMatcher.js.map +2 -2
  220. package/dist/utils/agentLoader.js +69 -35
  221. package/dist/utils/agentLoader.js.map +2 -2
  222. package/dist/utils/agentStorage.js.map +2 -2
  223. package/dist/utils/async.js +163 -0
  224. package/dist/utils/async.js.map +7 -0
  225. package/dist/utils/autoUpdater.js +8 -2
  226. package/dist/utils/autoUpdater.js.map +2 -2
  227. package/dist/utils/commands.js +23 -11
  228. package/dist/utils/commands.js.map +2 -2
  229. package/dist/utils/commonUnixCommands.js +3 -1
  230. package/dist/utils/commonUnixCommands.js.map +2 -2
  231. package/dist/utils/compressionMode.js.map +2 -2
  232. package/dist/utils/config.js +30 -14
  233. package/dist/utils/config.js.map +2 -2
  234. package/dist/utils/debugLogger.js.map +2 -2
  235. package/dist/utils/env.js.map +2 -2
  236. package/dist/utils/envConfig.js +82 -0
  237. package/dist/utils/envConfig.js.map +7 -0
  238. package/dist/utils/errorHandling.js +89 -0
  239. package/dist/utils/errorHandling.js.map +7 -0
  240. package/dist/utils/expertChatStorage.js.map +2 -2
  241. package/dist/utils/fuzzyMatcher.js +13 -7
  242. package/dist/utils/fuzzyMatcher.js.map +2 -2
  243. package/dist/utils/hookManager.js +14 -4
  244. package/dist/utils/hookManager.js.map +2 -2
  245. package/dist/utils/log.js.map +2 -2
  246. package/dist/utils/marketplaceManager.js +44 -9
  247. package/dist/utils/marketplaceManager.js.map +2 -2
  248. package/dist/utils/messageContextManager.js.map +1 -1
  249. package/dist/utils/messages.js +6 -3
  250. package/dist/utils/messages.js.map +2 -2
  251. package/dist/utils/model.js +3 -1
  252. package/dist/utils/model.js.map +2 -2
  253. package/dist/utils/pluginInstaller.js +3 -15
  254. package/dist/utils/pluginInstaller.js.map +2 -2
  255. package/dist/utils/pluginLoader.js +41 -13
  256. package/dist/utils/pluginLoader.js.map +2 -2
  257. package/dist/utils/pluginRegistry.js.map +2 -2
  258. package/dist/utils/pluginValidator.js +71 -49
  259. package/dist/utils/pluginValidator.js.map +2 -2
  260. package/dist/utils/ptyCompat.js.map +2 -2
  261. package/dist/utils/roundConverter.js.map +2 -2
  262. package/dist/utils/secureFile.js +43 -14
  263. package/dist/utils/secureFile.js.map +2 -2
  264. package/dist/utils/sessionState.js.map +2 -2
  265. package/dist/utils/skillLoader.js.map +2 -2
  266. package/dist/utils/teamConfig.js +7 -4
  267. package/dist/utils/teamConfig.js.map +2 -2
  268. package/dist/utils/theme.js.map +2 -2
  269. package/dist/utils/thinking.js.map +2 -2
  270. package/dist/utils/unaryLogging.js.map +2 -2
  271. package/dist/version.js +2 -2
  272. package/dist/version.js.map +1 -1
  273. package/package.json +5 -5
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/SkillTool/SkillTool.tsx"],
4
- "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport {\n loadAllSkills,\n getSkill,\n loadSkillContent,\n searchSkills,\n getSkillCount,\n} from '@utils/skillLoader'\nimport { DESCRIPTION, PROMPT } from './prompt'\n\nconst inputSchema = z.strictObject({\n action: z\n .enum(['list', 'load', 'search'])\n .describe('Action to perform: list all skills, load a specific skill, or search skills'),\n name: z\n .string()\n .optional()\n .describe('Name of skill to load (required for \"load\" action)'),\n query: z\n .string()\n .optional()\n .describe('Search query (required for \"search\" action)'),\n})\n\ntype SkillToolOutput =\n | { type: 'list'; skills: Array<{ name: string; description: string; plugin: string }> }\n | { type: 'load'; skill: { name: string; description: string; plugin: string; content: string } }\n | { type: 'search'; skills: Array<{ name: string; description: string; plugin: string }>; query: string }\n\nexport const SkillTool = {\n name: 'Skill',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Skill'\n },\n async isEnabled() {\n // Enable if there are any skills available\n return getSkillCount() > 0\n },\n isReadOnly() {\n return true // Skills are read-only resources\n },\n isConcurrencySafe() {\n return true // Reading skills is safe for concurrent execution\n },\n needsPermissions() {\n return false // No permissions needed for reading skills\n },\n renderResultForAssistant(output: SkillToolOutput) {\n if (output.type === 'list') {\n if (output.skills.length === 0) {\n return 'No skills available. Install plugins with skills to use this feature.'\n }\n\n const skillsList = output.skills\n .map((skill) => `- **${skill.name}** (${skill.plugin}): ${skill.description}`)\n .join('\\n')\n\n return `Available skills (${output.skills.length}):\\n\\n${skillsList}\\n\\nUse the \"load\" action to get full skill content.`\n }\n\n if (output.type === 'search') {\n if (output.skills.length === 0) {\n return `No skills found matching \"${output.query}\".`\n }\n\n const skillsList = output.skills\n .map((skill) => `- **${skill.name}** (${skill.plugin}): ${skill.description}`)\n .join('\\n')\n\n return `Skills matching \"${output.query}\" (${output.skills.length}):\\n\\n${skillsList}\\n\\nUse the \"load\" action to get full skill content.`\n }\n\n if (output.type === 'load') {\n const { skill } = output\n return `# Skill: ${skill.name}\n\n**Plugin**: ${skill.plugin}\n**Description**: ${skill.description}\n\n---\n\n${skill.content}\n\n---\n\n*End of skill content. Apply these instructions to complete your task.*`\n }\n\n return 'Unknown skill operation'\n },\n renderToolUseMessage(input, { verbose }) {\n if (input.action === 'list') {\n return 'Listing all available skills'\n }\n if (input.action === 'load' && input.name) {\n return `Loading skill: ${input.name}`\n }\n if (input.action === 'search' && input.query) {\n return `Searching skills for: ${input.query}`\n }\n return Object.entries(input)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: SkillToolOutput) {\n if (output.type === 'list') {\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Text color=\"green\">\n \u2713 Found {output.skills.length} skill{output.skills.length !== 1 ? 's' : ''}\n </Text>\n {output.skills.slice(0, 10).map((skill, i) => (\n <Box key={i} flexDirection=\"column\">\n <Text>\n <Text bold>{skill.name}</Text>\n <Text dimColor> ({skill.plugin})</Text>\n </Text>\n <Text dimColor> {skill.description}</Text>\n </Box>\n ))}\n {output.skills.length > 10 && (\n <Text dimColor> ... and {output.skills.length - 10} more</Text>\n )}\n </Box>\n )\n }\n\n if (output.type === 'search') {\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Text color=\"green\">\n \u2713 Found {output.skills.length} skill{output.skills.length !== 1 ? 's' : ''} matching &quot;{output.query}&quot;\n </Text>\n {output.skills.slice(0, 10).map((skill, i) => (\n <Box key={i} flexDirection=\"column\">\n <Text>\n <Text bold>{skill.name}</Text>\n <Text dimColor> ({skill.plugin})</Text>\n </Text>\n <Text dimColor> {skill.description}</Text>\n </Box>\n ))}\n {output.skills.length > 10 && (\n <Text dimColor> ... and {output.skills.length - 10} more</Text>\n )}\n </Box>\n )\n }\n\n if (output.type === 'load') {\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Text color=\"green\">\u2713 Loaded skill: {output.skill.name}</Text>\n <Text dimColor> Plugin: {output.skill.plugin}</Text>\n <Text dimColor> Content: {output.skill.content.length} characters</Text>\n </Box>\n )\n }\n\n return (\n <Box paddingLeft={2}>\n <Text>Skill operation completed</Text>\n </Box>\n )\n },\n async validateInput(input) {\n if (input.action === 'load') {\n if (!input.name) {\n return {\n result: false,\n message: 'Skill name is required for \"load\" action',\n }\n }\n\n const skill = getSkill(input.name)\n if (!skill) {\n const allSkills = loadAllSkills()\n const availableNames = allSkills.map((s) => s.name).join(', ')\n return {\n result: false,\n message: `Skill \"${input.name}\" not found. Available skills: ${availableNames}`,\n }\n }\n }\n\n if (input.action === 'search') {\n if (!input.query) {\n return {\n result: false,\n message: 'Query is required for \"search\" action',\n }\n }\n }\n\n return { result: true }\n },\n async *call(input) {\n try {\n // List all skills\n if (input.action === 'list') {\n const skills = loadAllSkills()\n const skillsList = skills.map((skill) => ({\n name: skill.name,\n description: skill.config.description,\n plugin: skill.pluginName,\n }))\n\n const output: SkillToolOutput = {\n type: 'list',\n skills: skillsList,\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Load specific skill\n if (input.action === 'load' && input.name) {\n const skill = getSkill(input.name)\n if (!skill) {\n throw new Error(`Skill \"${input.name}\" not found`)\n }\n\n // Load full content\n const content = await loadSkillContent(skill)\n\n const output: SkillToolOutput = {\n type: 'load',\n skill: {\n name: skill.name,\n description: skill.config.description,\n plugin: skill.pluginName,\n content,\n },\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Search skills\n if (input.action === 'search' && input.query) {\n const skills = searchSkills(input.query)\n const skillsList = skills.map((skill) => ({\n name: skill.name,\n description: skill.config.description,\n plugin: skill.pluginName,\n }))\n\n const output: SkillToolOutput = {\n type: 'search',\n skills: skillsList,\n query: input.query,\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n throw new Error('Invalid skill action or missing required parameters')\n } catch (error) {\n throw new Error(\n `Skill operation failed: ${error instanceof Error ? error.message : String(error)}`\n )\n }\n },\n} satisfies Tool<typeof inputSchema, SkillToolOutput>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport {\n loadAllSkills,\n getSkill,\n loadSkillContent,\n searchSkills,\n getSkillCount,\n} from '@utils/skillLoader'\nimport { DESCRIPTION, PROMPT } from './prompt'\n\nconst inputSchema = z.strictObject({\n action: z\n .enum(['list', 'load', 'search'])\n .describe(\n 'Action to perform: list all skills, load a specific skill, or search skills',\n ),\n name: z\n .string()\n .optional()\n .describe('Name of skill to load (required for \"load\" action)'),\n query: z\n .string()\n .optional()\n .describe('Search query (required for \"search\" action)'),\n})\n\ntype SkillToolOutput =\n | {\n type: 'list'\n skills: Array<{ name: string; description: string; plugin: string }>\n }\n | {\n type: 'load'\n skill: {\n name: string\n description: string\n plugin: string\n content: string\n }\n }\n | {\n type: 'search'\n skills: Array<{ name: string; description: string; plugin: string }>\n query: string\n }\n\nexport const SkillTool = {\n name: 'Skill',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Skill'\n },\n async isEnabled() {\n // Enable if there are any skills available\n return getSkillCount() > 0\n },\n isReadOnly() {\n return true // Skills are read-only resources\n },\n isConcurrencySafe() {\n return true // Reading skills is safe for concurrent execution\n },\n needsPermissions() {\n return false // No permissions needed for reading skills\n },\n renderResultForAssistant(output: SkillToolOutput) {\n if (output.type === 'list') {\n if (output.skills.length === 0) {\n return 'No skills available. Install plugins with skills to use this feature.'\n }\n\n const skillsList = output.skills\n .map(\n skill =>\n `- **${skill.name}** (${skill.plugin}): ${skill.description}`,\n )\n .join('\\n')\n\n return `Available skills (${output.skills.length}):\\n\\n${skillsList}\\n\\nUse the \"load\" action to get full skill content.`\n }\n\n if (output.type === 'search') {\n if (output.skills.length === 0) {\n return `No skills found matching \"${output.query}\".`\n }\n\n const skillsList = output.skills\n .map(\n skill =>\n `- **${skill.name}** (${skill.plugin}): ${skill.description}`,\n )\n .join('\\n')\n\n return `Skills matching \"${output.query}\" (${output.skills.length}):\\n\\n${skillsList}\\n\\nUse the \"load\" action to get full skill content.`\n }\n\n if (output.type === 'load') {\n const { skill } = output\n return `# Skill: ${skill.name}\n\n**Plugin**: ${skill.plugin}\n**Description**: ${skill.description}\n\n---\n\n${skill.content}\n\n---\n\n*End of skill content. Apply these instructions to complete your task.*`\n }\n\n return 'Unknown skill operation'\n },\n renderToolUseMessage(input, { verbose }) {\n if (input.action === 'list') {\n return 'Listing all available skills'\n }\n if (input.action === 'load' && input.name) {\n return `Loading skill: ${input.name}`\n }\n if (input.action === 'search' && input.query) {\n return `Searching skills for: ${input.query}`\n }\n return Object.entries(input)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: SkillToolOutput) {\n // Guard against undefined or null output\n if (!output || !output.type) {\n return (\n <Box paddingLeft={2}>\n <Text>Skill operation completed</Text>\n </Box>\n )\n }\n\n if (output.type === 'list') {\n const skills = output.skills || []\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Text color=\"green\">\n \u2713 Found {skills.length} skill\n {skills.length !== 1 ? 's' : ''}\n </Text>\n {skills.slice(0, 10).map((skill, i) => (\n <Box key={i} flexDirection=\"column\">\n <Text>\n <Text bold>{skill?.name || 'Unknown'}</Text>\n <Text dimColor> ({skill?.plugin || 'Unknown'})</Text>\n </Text>\n <Text dimColor> {skill?.description || ''}</Text>\n </Box>\n ))}\n {skills.length > 10 && (\n <Text dimColor> ... and {skills.length - 10} more</Text>\n )}\n </Box>\n )\n }\n\n if (output.type === 'search') {\n const skills = output.skills || []\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Text color=\"green\">\n \u2713 Found {skills.length} skill\n {skills.length !== 1 ? 's' : ''} matching &quot;\n {output.query || ''}&quot;\n </Text>\n {skills.slice(0, 10).map((skill, i) => (\n <Box key={i} flexDirection=\"column\">\n <Text>\n <Text bold>{skill?.name || 'Unknown'}</Text>\n <Text dimColor> ({skill?.plugin || 'Unknown'})</Text>\n </Text>\n <Text dimColor> {skill?.description || ''}</Text>\n </Box>\n ))}\n {skills.length > 10 && (\n <Text dimColor> ... and {skills.length - 10} more</Text>\n )}\n </Box>\n )\n }\n\n if (output.type === 'load') {\n const skill = output.skill || { name: '', description: '', plugin: '', content: '' }\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Text color=\"green\">\u2713 Loaded skill: {skill.name || 'Unknown'}</Text>\n <Text dimColor> Plugin: {skill.plugin || 'Unknown'}</Text>\n <Text dimColor>\n {' '}\n Content: {(skill.content || '').length} characters\n </Text>\n </Box>\n )\n }\n\n return (\n <Box paddingLeft={2}>\n <Text>Skill operation completed</Text>\n </Box>\n )\n },\n async validateInput(input) {\n if (input.action === 'load') {\n if (!input.name) {\n return {\n result: false,\n message: 'Skill name is required for \"load\" action',\n }\n }\n\n const skill = getSkill(input.name)\n if (!skill) {\n const allSkills = loadAllSkills()\n const availableNames = allSkills.map(s => s.name).join(', ')\n return {\n result: false,\n message: `Skill \"${input.name}\" not found. Available skills: ${availableNames}`,\n }\n }\n }\n\n if (input.action === 'search') {\n if (!input.query) {\n return {\n result: false,\n message: 'Query is required for \"search\" action',\n }\n }\n }\n\n return { result: true }\n },\n async *call(input) {\n try {\n // List all skills\n if (input.action === 'list') {\n const skills = loadAllSkills()\n const skillsList = skills.map(skill => ({\n name: skill.name,\n description: skill.config.description,\n plugin: skill.pluginName,\n }))\n\n const output: SkillToolOutput = {\n type: 'list',\n skills: skillsList,\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Load specific skill\n if (input.action === 'load' && input.name) {\n const skill = getSkill(input.name)\n if (!skill) {\n throw new Error(`Skill \"${input.name}\" not found`)\n }\n\n // Load full content\n const content = await loadSkillContent(skill)\n\n const output: SkillToolOutput = {\n type: 'load',\n skill: {\n name: skill.name,\n description: skill.config.description,\n plugin: skill.pluginName,\n content,\n },\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Search skills\n if (input.action === 'search' && input.query) {\n const skills = searchSkills(input.query)\n const skillsList = skills.map(skill => ({\n name: skill.name,\n description: skill.config.description,\n plugin: skill.pluginName,\n }))\n\n const output: SkillToolOutput = {\n type: 'search',\n skills: skillsList,\n query: input.query,\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n throw new Error('Invalid skill action or missing required parameters')\n } catch (error) {\n throw new Error(\n `Skill operation failed: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n },\n} satisfies Tool<typeof inputSchema, SkillToolOutput>\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -26,7 +26,10 @@ import { getTheme } from "../../utils/theme.js";
26
26
  import { generateAgentId } from "../../utils/agentStorage.js";
27
27
  import { getTaskTools, getPrompt } from "./prompt.js";
28
28
  import { TOOL_NAME } from "./constants.js";
29
- import { getAgentByType, getAvailableAgentTypes } from "../../utils/agentLoader.js";
29
+ import {
30
+ getAgentByType,
31
+ getAvailableAgentTypes
32
+ } from "../../utils/agentLoader.js";
30
33
  const inputSchema = z.object({
31
34
  description: z.string().describe("A short (3-5 word) description of the task"),
32
35
  prompt: z.string().describe("The task for the agent to perform"),
@@ -118,7 +121,9 @@ ${prompt}`;
118
121
  };
119
122
  yield {
120
123
  type: "progress",
121
- content: createAssistantMessage(`Prompt: ${prompt.length > 150 ? prompt.substring(0, 150) + "..." : prompt}`),
124
+ content: createAssistantMessage(
125
+ `Prompt: ${prompt.length > 150 ? prompt.substring(0, 150) + "..." : prompt}`
126
+ ),
122
127
  normalizedMessages: normalizeMessages(messages),
123
128
  tools
124
129
  };
@@ -127,8 +132,10 @@ ${prompt}`;
127
132
  getContext(),
128
133
  getMaxThinkingTokens(messages)
129
134
  ]);
130
- taskPrompt.push(`
131
- IMPORTANT: You are currently running as ${modelToUse}. You do not need to consult ${modelToUse} via AskExpertModel since you ARE ${modelToUse}. Complete tasks directly using your capabilities.`);
135
+ taskPrompt.push(
136
+ `
137
+ IMPORTANT: You are currently running as ${modelToUse}. You do not need to consult ${modelToUse} via AskExpertModel since you ARE ${modelToUse}. Complete tasks directly using your capabilities.`
138
+ );
132
139
  let toolUseCount = 0;
133
140
  const getSidechainNumber = memoize(
134
141
  () => getNextAvailableLogSidechainNumber(messageLogName, forkNumber)
@@ -231,7 +238,9 @@ IMPORTANT: You are currently running as ${modelToUse}. You do not need to consul
231
238
  ];
232
239
  yield {
233
240
  type: "progress",
234
- content: createAssistantMessage(`Task completed (${result.join(" \xB7 ")})`),
241
+ content: createAssistantMessage(
242
+ `Task completed (${result.join(" \xB7 ")})`
243
+ ),
235
244
  normalizedMessages,
236
245
  tools
237
246
  };
@@ -327,53 +336,30 @@ IMPORTANT: You are currently running as ${modelToUse}. You do not need to consul
327
336
  },
328
337
  renderToolUseRejectedMessage() {
329
338
  return /* @__PURE__ */ React.createElement(FallbackToolUseRejectedMessage, null);
339
+ },
340
+ renderToolResultMessage(content) {
341
+ const theme = getTheme();
342
+ if (!content) {
343
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Task completed"));
344
+ }
345
+ if (Array.isArray(content)) {
346
+ const textBlocks = content.filter(
347
+ (block) => block && block.type === "text"
348
+ );
349
+ const totalLength = textBlocks.reduce(
350
+ (sum, block) => sum + (block.text?.length || 0),
351
+ 0
352
+ );
353
+ const isInterrupted = content.some(
354
+ (block) => block && block.type === "text" && block.text === INTERRUPT_MESSAGE
355
+ );
356
+ if (isInterrupted) {
357
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Interrupted by user"));
358
+ }
359
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Text, null, "Task completed"), textBlocks.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, " ", "(", totalLength, " characters)"))));
360
+ }
361
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Task completed"));
330
362
  }
331
- // renderToolResultMessage(content) {
332
- // const theme = getTheme()
333
- // if (Array.isArray(content)) {
334
- // const textBlocks = content.filter(block => block.type === 'text')
335
- // const totalLength = textBlocks.reduce(
336
- // (sum, block) => sum + block.text.length,
337
- // 0,
338
- // )
339
- // // 🔧 CRITICAL FIX: Use exact match for interrupt detection, not .includes()
340
- // const isInterrupted = content.some(
341
- // block =>
342
- // block.type === 'text' && block.text === INTERRUPT_MESSAGE,
343
- // )
344
- // if (isInterrupted) {
345
- // // 🔧 CRITICAL FIX: Match original system interrupt rendering exactly
346
- // return (
347
- // <Box flexDirection="row">
348
- // <Text>&nbsp;&nbsp;⎿ &nbsp;</Text>
349
- // <Text color={theme.error}>Interrupted by user</Text>
350
- // </Box>
351
- // )
352
- // }
353
- // return (
354
- // <Box flexDirection="column">
355
- // <Box justifyContent="space-between" width="100%">
356
- // <Box flexDirection="row">
357
- // <Text>&nbsp;&nbsp;⎿ &nbsp;</Text>
358
- // <Text>Task completed</Text>
359
- // {textBlocks.length > 0 && (
360
- // <Text color={theme.secondaryText}>
361
- // {' '}
362
- // ({totalLength} characters)
363
- // </Text>
364
- // )}
365
- // </Box>
366
- // </Box>
367
- // </Box>
368
- // )
369
- // }
370
- // return (
371
- // <Box flexDirection="row">
372
- // <Text>&nbsp;&nbsp;⎿ &nbsp;</Text>
373
- // <Text color={theme.secondaryText}>Task completed</Text>
374
- // </Box>
375
- // )
376
- // },
377
363
  };
378
364
  export {
379
365
  TaskTool
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/TaskTool/TaskTool.tsx"],
4
- "sourcesContent": ["import { TextBlock } from '@anthropic-ai/sdk/resources/index.mjs'\nimport chalk from 'chalk'\nimport { last, memoize } from 'lodash-es'\nimport { EOL } from 'os'\nimport React, { useState, useEffect } from 'react'\nimport { Box, Text } from 'ink'\nimport { z } from 'zod'\nimport { Tool, ValidationResult } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { getAgentPrompt } from '@constants/prompts'\nimport { getContext } from '@context'\nimport { hasPermissionsToUseTool } from '@permissions'\nimport { AssistantMessage, Message as MessageType, query } from '@query'\nimport { formatDuration, formatNumber } from '@utils/format'\nimport {\n getMessagesPath,\n getNextAvailableLogSidechainNumber,\n overwriteLog,\n} from '@utils/log'\nimport { applyMarkdown } from '@utils/markdown'\nimport {\n createAssistantMessage,\n createUserMessage,\n getLastAssistantMessageId,\n INTERRUPT_MESSAGE,\n normalizeMessages,\n} from '@utils/messages'\nimport { getModelManager } from '@utils/model'\nimport { getMaxThinkingTokens } from '@utils/thinking'\nimport { getTheme } from '@utils/theme'\nimport { generateAgentId } from '@utils/agentStorage'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { getTaskTools, getPrompt } from './prompt'\nimport { TOOL_NAME } from './constants'\nimport { getActiveAgents, getAgentByType, getAvailableAgentTypes } from '@utils/agentLoader'\n\nconst inputSchema = z.object({\n description: z\n .string()\n .describe('A short (3-5 word) description of the task'),\n prompt: z.string().describe('The task for the agent to perform'),\n model_name: z\n .string()\n .optional()\n .describe(\n 'Optional: Specific model name to use for this task. If not provided, uses the default task model pointer.',\n ),\n subagent_type: z\n .string()\n .optional()\n .describe(\n 'The specialized agent type (MUST use hyphens, e.g., \"strategic-market-analyzer\"). For research/analysis use \"strategic-market-analyzer\" or \"business-analyst\", for data use \"data-scientist\", for general use \"general-purpose\". NEVER use underscores or invent names like \"researcher\".',\n ),\n})\n\nexport const TaskTool = {\n async prompt({ safeMode }) {\n // Ensure agent prompts remain compatible with Claude Code `.claude` agent packs\n return await getPrompt(safeMode)\n },\n name: TOOL_NAME,\n async description() {\n // Ensure metadata stays compatible with Claude Code `.claude` agent packs\n const availableTypes = await getAvailableAgentTypes()\n const typesList = availableTypes.slice(0, 10).join(', ') + (availableTypes.length > 10 ? '...' : '')\n return `Launch a specialized agent to handle tasks autonomously. CRITICAL: Use exact agent type names with hyphens (e.g., \"strategic-market-analyzer\", NOT \"researcher\" or \"market_analyzer\"). Available: ${typesList}`\n },\n inputSchema,\n \n async *call(\n { description, prompt, model_name, subagent_type },\n {\n abortController,\n options: { safeMode = false, forkNumber, messageLogName, verbose },\n readFileTimestamps,\n },\n ): AsyncGenerator<\n | { type: 'result'; data: TextBlock[]; resultForAssistant?: string }\n | { type: 'progress'; content: any; normalizedMessages?: any[]; tools?: any[] },\n void,\n unknown\n > {\n const startTime = Date.now()\n \n // Default to general-purpose if no subagent_type specified\n const agentType = subagent_type || 'general-purpose'\n \n // Apply subagent configuration\n let effectivePrompt = prompt\n let effectiveModel = model_name || 'task'\n let toolFilter = null\n let temperature = undefined\n \n // Load agent configuration dynamically\n if (agentType) {\n const agentConfig = await getAgentByType(agentType)\n \n if (!agentConfig) {\n // If agent type not found, return helpful message instead of throwing\n const availableTypes = await getAvailableAgentTypes()\n const helpMessage = `Agent type '${agentType}' not found.\\n\\nAvailable agents:\\n${availableTypes.map(t => ` \u2022 ${t}`).join('\\n')}\\n\\nUse /agents command to manage agent configurations.`\n \n yield {\n type: 'result',\n data: [{ type: 'text', text: helpMessage }] as TextBlock[],\n resultForAssistant: helpMessage,\n }\n return\n }\n \n // Apply system prompt if configured\n if (agentConfig.systemPrompt) {\n effectivePrompt = `${agentConfig.systemPrompt}\\n\\n${prompt}`\n }\n \n // Apply model if not overridden by model_name parameter\n if (!model_name && agentConfig.model_name) {\n // Support inherit: keep pointer-based default\n if (agentConfig.model_name !== 'inherit') {\n effectiveModel = agentConfig.model_name as string\n }\n }\n \n // Store tool filter for later application\n toolFilter = agentConfig.tools\n \n // Note: temperature is not currently in our agent configs\n // but could be added in the future\n }\n \n const messages: MessageType[] = [createUserMessage(effectivePrompt)]\n let tools = await getTaskTools(safeMode)\n \n // Apply tool filtering if specified by subagent config\n if (toolFilter) {\n // Back-compat: ['*'] means all tools\n const isAllArray = Array.isArray(toolFilter) && toolFilter.length === 1 && toolFilter[0] === '*'\n if (toolFilter === '*' || isAllArray) {\n // no-op, keep all tools\n } else if (Array.isArray(toolFilter)) {\n tools = tools.filter(tool => toolFilter.includes(tool.name))\n }\n }\n\n // Model already resolved in effectiveModel variable above\n const modelToUse = effectiveModel\n\n // Display initial task information with separate progress lines\n yield {\n type: 'progress',\n content: createAssistantMessage(`Starting agent: ${agentType}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n \n yield {\n type: 'progress', \n content: createAssistantMessage(`Using model: ${modelToUse}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n \n yield {\n type: 'progress',\n content: createAssistantMessage(`Task: ${description}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n \n yield {\n type: 'progress',\n content: createAssistantMessage(`Prompt: ${prompt.length > 150 ? prompt.substring(0, 150) + '...' : prompt}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n const [taskPrompt, context, maxThinkingTokens] = await Promise.all([\n getAgentPrompt(),\n getContext(),\n getMaxThinkingTokens(messages),\n ])\n \n // Inject model context to prevent self-referential expert consultations\n taskPrompt.push(`\\nIMPORTANT: You are currently running as ${modelToUse}. You do not need to consult ${modelToUse} via AskExpertModel since you ARE ${modelToUse}. Complete tasks directly using your capabilities.`)\n\n let toolUseCount = 0\n\n const getSidechainNumber = memoize(() =>\n getNextAvailableLogSidechainNumber(messageLogName, forkNumber),\n )\n\n // Generate unique Task ID for this task execution\n const taskId = generateAgentId()\n\n // \uD83D\uDD27 ULTRA SIMPLIFIED: Exact original AgentTool pattern\n // Build query options, adding temperature if specified\n const queryOptions = {\n safeMode,\n forkNumber,\n messageLogName,\n tools,\n commands: [],\n verbose,\n maxThinkingTokens,\n model: modelToUse,\n }\n \n // Add temperature if specified by subagent config\n if (temperature !== undefined) {\n queryOptions['temperature'] = temperature\n }\n \n for await (const message of query(\n messages,\n taskPrompt,\n context,\n hasPermissionsToUseTool,\n {\n abortController,\n options: queryOptions,\n messageId: getLastAssistantMessageId(messages),\n agentId: taskId,\n readFileTimestamps,\n setToolJSX: () => {}, // No-op implementation for TaskTool\n },\n )) {\n messages.push(message)\n\n overwriteLog(\n getMessagesPath(messageLogName, forkNumber, getSidechainNumber()),\n messages.filter(_ => _.type !== 'progress'),\n )\n\n if (message.type !== 'assistant') {\n continue\n }\n\n const normalizedMessages = normalizeMessages(messages)\n \n // Process tool uses and text content for better visibility\n for (const content of message.message.content) {\n if (content.type === 'text' && content.text && content.text !== INTERRUPT_MESSAGE) {\n // Show agent's reasoning/responses\n const preview = content.text.length > 200 ? content.text.substring(0, 200) + '...' : content.text\n yield {\n type: 'progress',\n content: createAssistantMessage(`${preview}`),\n normalizedMessages,\n tools,\n }\n } else if (content.type === 'tool_use') {\n toolUseCount++\n \n // Show which tool is being used with agent context\n const toolMessage = normalizedMessages.find(\n _ =>\n _.type === 'assistant' &&\n _.message.content[0]?.type === 'tool_use' &&\n _.message.content[0].id === content.id,\n ) as AssistantMessage\n \n if (toolMessage) {\n // Clone and modify the message to show agent context\n const modifiedMessage = {\n ...toolMessage,\n message: {\n ...toolMessage.message,\n content: toolMessage.message.content.map(c => {\n if (c.type === 'tool_use' && c.id === content.id) {\n // Add agent context to tool name display\n return {\n ...c,\n name: c.name // Keep original name, UI will handle display\n }\n }\n return c\n })\n }\n }\n \n yield {\n type: 'progress',\n content: modifiedMessage,\n normalizedMessages,\n tools,\n }\n }\n }\n }\n }\n\n const normalizedMessages = normalizeMessages(messages)\n const lastMessage = last(messages)\n if (lastMessage?.type !== 'assistant') {\n throw new Error('Last message was not an assistant message')\n }\n\n // \uD83D\uDD27 CRITICAL FIX: Match original AgentTool interrupt handling pattern exactly\n if (\n lastMessage.message.content.some(\n _ => _.type === 'text' && _.text === INTERRUPT_MESSAGE,\n )\n ) {\n // Skip progress yield - only yield final result\n } else {\n const result = [\n toolUseCount === 1 ? '1 tool use' : `${toolUseCount} tool uses`,\n formatNumber(\n (lastMessage.message.usage.cache_creation_input_tokens ?? 0) +\n (lastMessage.message.usage.cache_read_input_tokens ?? 0) +\n lastMessage.message.usage.input_tokens +\n lastMessage.message.usage.output_tokens,\n ) + ' tokens',\n formatDuration(Date.now() - startTime),\n ]\n yield {\n type: 'progress',\n content: createAssistantMessage(`Task completed (${result.join(' \u00B7 ')})`),\n normalizedMessages,\n tools,\n }\n }\n\n // Output is an AssistantMessage, but since TaskTool is a tool, it needs\n // to serialize its response to UserMessage-compatible content.\n const data = lastMessage.message.content.filter(_ => _.type === 'text')\n yield {\n type: 'result',\n data,\n resultForAssistant: this.renderResultForAssistant(data),\n }\n },\n\n isReadOnly() {\n return true // for now...\n },\n isConcurrencySafe() {\n return true // Task tool supports concurrent execution in official implementation\n },\n async validateInput(input, context) {\n if (!input.description || typeof input.description !== 'string') {\n return {\n result: false,\n message: 'Description is required and must be a string',\n }\n }\n if (!input.prompt || typeof input.prompt !== 'string') {\n return {\n result: false,\n message: 'Prompt is required and must be a string',\n }\n }\n\n // Model validation - similar to Edit tool error handling\n if (input.model_name) {\n const modelManager = getModelManager()\n const availableModels = modelManager.getAllAvailableModelNames()\n\n if (!availableModels.includes(input.model_name)) {\n return {\n result: false,\n message: `Model '${input.model_name}' does not exist. Available models: ${availableModels.join(', ')}`,\n meta: {\n model_name: input.model_name,\n availableModels,\n },\n }\n }\n }\n\n // Validate subagent_type if provided\n if (input.subagent_type) {\n const availableTypes = await getAvailableAgentTypes()\n if (!availableTypes.includes(input.subagent_type)) {\n return {\n result: false,\n message: `Agent type '${input.subagent_type}' does not exist. Available types: ${availableTypes.join(', ')}`,\n meta: {\n subagent_type: input.subagent_type,\n availableTypes,\n },\n }\n }\n }\n\n return { result: true }\n },\n async isEnabled() {\n return true\n },\n userFacingName(input?: any) {\n // Return agent name with proper prefix\n const agentType = input?.subagent_type || 'general-purpose'\n return `agent-${agentType}`\n },\n needsPermissions() {\n return false\n },\n renderResultForAssistant(data: TextBlock[]) {\n return data.map(block => block.type === 'text' ? block.text : '').join('\\n')\n },\n renderToolUseMessage({ description, prompt, model_name, subagent_type }, { verbose }) {\n if (!description || !prompt) return null\n\n const modelManager = getModelManager()\n const defaultTaskModel = modelManager.getModelName('task')\n const actualModel = model_name || defaultTaskModel\n const agentType = subagent_type || 'general-purpose'\n const promptPreview =\n prompt.length > 80 ? prompt.substring(0, 80) + '...' : prompt\n\n const theme = getTheme()\n \n if (verbose) {\n return (\n <Box flexDirection=\"column\">\n <Text>\n [{agentType}] {actualModel}: {description}\n </Text>\n <Box\n paddingLeft={2}\n borderLeftStyle=\"single\"\n borderLeftColor={theme.secondaryBorder}\n >\n <Text color={theme.secondaryText}>{promptPreview}</Text>\n </Box>\n </Box>\n )\n }\n\n // Simple display: agent type, model and description\n return `[${agentType}] ${actualModel}: ${description}`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n // renderToolResultMessage(content) {\n // const theme = getTheme()\n\n // if (Array.isArray(content)) {\n // const textBlocks = content.filter(block => block.type === 'text')\n // const totalLength = textBlocks.reduce(\n // (sum, block) => sum + block.text.length,\n // 0,\n // )\n // // \uD83D\uDD27 CRITICAL FIX: Use exact match for interrupt detection, not .includes()\n // const isInterrupted = content.some(\n // block =>\n // block.type === 'text' && block.text === INTERRUPT_MESSAGE,\n // )\n\n // if (isInterrupted) {\n // // \uD83D\uDD27 CRITICAL FIX: Match original system interrupt rendering exactly\n // return (\n // <Box flexDirection=\"row\">\n // <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n // <Text color={theme.error}>Interrupted by user</Text>\n // </Box>\n // )\n // }\n\n // return (\n // <Box flexDirection=\"column\">\n // <Box justifyContent=\"space-between\" width=\"100%\">\n // <Box flexDirection=\"row\">\n // <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n // <Text>Task completed</Text>\n // {textBlocks.length > 0 && (\n // <Text color={theme.secondaryText}>\n // {' '}\n // ({totalLength} characters)\n // </Text>\n // )}\n // </Box>\n // </Box>\n // </Box>\n // )\n // }\n\n // return (\n // <Box flexDirection=\"row\">\n // <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n // <Text color={theme.secondaryText}>Task completed</Text>\n // </Box>\n // )\n // },\n} satisfies Tool<typeof inputSchema, TextBlock[]>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { TextBlock } from '@anthropic-ai/sdk/resources/index.mjs'\nimport chalk from 'chalk'\nimport { last, memoize } from 'lodash-es'\nimport { EOL } from 'os'\nimport React, { useState, useEffect } from 'react'\nimport { Box, Text } from 'ink'\nimport { z } from 'zod'\nimport { Tool, ValidationResult } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { getAgentPrompt } from '@constants/prompts'\nimport { getContext } from '@context'\nimport { hasPermissionsToUseTool } from '@permissions'\nimport { AssistantMessage, Message as MessageType, query } from '@query'\nimport { formatDuration, formatNumber } from '@utils/format'\nimport {\n getMessagesPath,\n getNextAvailableLogSidechainNumber,\n overwriteLog,\n} from '@utils/log'\nimport { applyMarkdown } from '@utils/markdown'\nimport {\n createAssistantMessage,\n createUserMessage,\n getLastAssistantMessageId,\n INTERRUPT_MESSAGE,\n normalizeMessages,\n} from '@utils/messages'\nimport { getModelManager } from '@utils/model'\nimport { getMaxThinkingTokens } from '@utils/thinking'\nimport { getTheme } from '@utils/theme'\nimport { generateAgentId } from '@utils/agentStorage'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { getTaskTools, getPrompt } from './prompt'\nimport { TOOL_NAME } from './constants'\nimport {\n getActiveAgents,\n getAgentByType,\n getAvailableAgentTypes,\n} from '@utils/agentLoader'\n\nconst inputSchema = z.object({\n description: z\n .string()\n .describe('A short (3-5 word) description of the task'),\n prompt: z.string().describe('The task for the agent to perform'),\n model_name: z\n .string()\n .optional()\n .describe(\n 'Optional: Specific model name to use for this task. If not provided, uses the default task model pointer.',\n ),\n subagent_type: z\n .string()\n .optional()\n .describe(\n 'The specialized agent type (MUST use hyphens, e.g., \"strategic-market-analyzer\"). For research/analysis use \"strategic-market-analyzer\" or \"business-analyst\", for data use \"data-scientist\", for general use \"general-purpose\". NEVER use underscores or invent names like \"researcher\".',\n ),\n})\n\nexport const TaskTool = {\n async prompt({ safeMode }) {\n // Ensure agent prompts remain compatible with Claude Code `.claude` agent packs\n return await getPrompt(safeMode)\n },\n name: TOOL_NAME,\n async description() {\n // Ensure metadata stays compatible with Claude Code `.claude` agent packs\n const availableTypes = await getAvailableAgentTypes()\n const typesList =\n availableTypes.slice(0, 10).join(', ') +\n (availableTypes.length > 10 ? '...' : '')\n return `Launch a specialized agent to handle tasks autonomously. CRITICAL: Use exact agent type names with hyphens (e.g., \"strategic-market-analyzer\", NOT \"researcher\" or \"market_analyzer\"). Available: ${typesList}`\n },\n inputSchema,\n\n async *call(\n { description, prompt, model_name, subagent_type },\n {\n abortController,\n options: { safeMode = false, forkNumber, messageLogName, verbose },\n readFileTimestamps,\n },\n ): AsyncGenerator<\n | { type: 'result'; data: TextBlock[]; resultForAssistant?: string }\n | {\n type: 'progress'\n content: any\n normalizedMessages?: any[]\n tools?: any[]\n },\n void,\n unknown\n > {\n const startTime = Date.now()\n\n // Default to general-purpose if no subagent_type specified\n const agentType = subagent_type || 'general-purpose'\n\n // Apply subagent configuration\n let effectivePrompt = prompt\n let effectiveModel = model_name || 'task'\n let toolFilter = null\n let temperature = undefined\n\n // Load agent configuration dynamically\n if (agentType) {\n const agentConfig = await getAgentByType(agentType)\n\n if (!agentConfig) {\n // If agent type not found, return helpful message instead of throwing\n const availableTypes = await getAvailableAgentTypes()\n const helpMessage = `Agent type '${agentType}' not found.\\n\\nAvailable agents:\\n${availableTypes.map(t => ` \u2022 ${t}`).join('\\n')}\\n\\nUse /agents command to manage agent configurations.`\n\n yield {\n type: 'result',\n data: [{ type: 'text', text: helpMessage }] as TextBlock[],\n resultForAssistant: helpMessage,\n }\n return\n }\n\n // Apply system prompt if configured\n if (agentConfig.systemPrompt) {\n effectivePrompt = `${agentConfig.systemPrompt}\\n\\n${prompt}`\n }\n\n // Apply model if not overridden by model_name parameter\n if (!model_name && agentConfig.model_name) {\n // Support inherit: keep pointer-based default\n if (agentConfig.model_name !== 'inherit') {\n effectiveModel = agentConfig.model_name as string\n }\n }\n\n // Store tool filter for later application\n toolFilter = agentConfig.tools\n\n // Note: temperature is not currently in our agent configs\n // but could be added in the future\n }\n\n const messages: MessageType[] = [createUserMessage(effectivePrompt)]\n let tools = await getTaskTools(safeMode)\n\n // Apply tool filtering if specified by subagent config\n if (toolFilter) {\n // Back-compat: ['*'] means all tools\n const isAllArray =\n Array.isArray(toolFilter) &&\n toolFilter.length === 1 &&\n toolFilter[0] === '*'\n if (toolFilter === '*' || isAllArray) {\n // no-op, keep all tools\n } else if (Array.isArray(toolFilter)) {\n tools = tools.filter(tool => toolFilter.includes(tool.name))\n }\n }\n\n // Model already resolved in effectiveModel variable above\n const modelToUse = effectiveModel\n\n // Display initial task information with separate progress lines\n yield {\n type: 'progress',\n content: createAssistantMessage(`Starting agent: ${agentType}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(`Using model: ${modelToUse}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(`Task: ${description}`),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n yield {\n type: 'progress',\n content: createAssistantMessage(\n `Prompt: ${prompt.length > 150 ? prompt.substring(0, 150) + '...' : prompt}`,\n ),\n normalizedMessages: normalizeMessages(messages),\n tools,\n }\n\n const [taskPrompt, context, maxThinkingTokens] = await Promise.all([\n getAgentPrompt(),\n getContext(),\n getMaxThinkingTokens(messages),\n ])\n\n // Inject model context to prevent self-referential expert consultations\n taskPrompt.push(\n `\\nIMPORTANT: You are currently running as ${modelToUse}. You do not need to consult ${modelToUse} via AskExpertModel since you ARE ${modelToUse}. Complete tasks directly using your capabilities.`,\n )\n\n let toolUseCount = 0\n\n const getSidechainNumber = memoize(() =>\n getNextAvailableLogSidechainNumber(messageLogName, forkNumber),\n )\n\n // Generate unique Task ID for this task execution\n const taskId = generateAgentId()\n\n // \uD83D\uDD27 ULTRA SIMPLIFIED: Exact original AgentTool pattern\n // Build query options, adding temperature if specified\n const queryOptions = {\n safeMode,\n forkNumber,\n messageLogName,\n tools,\n commands: [],\n verbose,\n maxThinkingTokens,\n model: modelToUse,\n }\n\n // Add temperature if specified by subagent config\n if (temperature !== undefined) {\n queryOptions['temperature'] = temperature\n }\n\n for await (const message of query(\n messages,\n taskPrompt,\n context,\n hasPermissionsToUseTool,\n {\n abortController,\n options: queryOptions,\n messageId: getLastAssistantMessageId(messages),\n agentId: taskId,\n readFileTimestamps,\n setToolJSX: () => {}, // No-op implementation for TaskTool\n },\n )) {\n messages.push(message)\n\n overwriteLog(\n getMessagesPath(messageLogName, forkNumber, getSidechainNumber()),\n messages.filter(_ => _.type !== 'progress'),\n )\n\n if (message.type !== 'assistant') {\n continue\n }\n\n const normalizedMessages = normalizeMessages(messages)\n\n // Process tool uses and text content for better visibility\n for (const content of message.message.content) {\n if (\n content.type === 'text' &&\n content.text &&\n content.text !== INTERRUPT_MESSAGE\n ) {\n // Show agent's reasoning/responses\n const preview =\n content.text.length > 200\n ? content.text.substring(0, 200) + '...'\n : content.text\n yield {\n type: 'progress',\n content: createAssistantMessage(`${preview}`),\n normalizedMessages,\n tools,\n }\n } else if (content.type === 'tool_use') {\n toolUseCount++\n\n // Show which tool is being used with agent context\n const toolMessage = normalizedMessages.find(\n _ =>\n _.type === 'assistant' &&\n _.message.content[0]?.type === 'tool_use' &&\n _.message.content[0].id === content.id,\n ) as AssistantMessage\n\n if (toolMessage) {\n // Clone and modify the message to show agent context\n const modifiedMessage = {\n ...toolMessage,\n message: {\n ...toolMessage.message,\n content: toolMessage.message.content.map(c => {\n if (c.type === 'tool_use' && c.id === content.id) {\n // Add agent context to tool name display\n return {\n ...c,\n name: c.name, // Keep original name, UI will handle display\n }\n }\n return c\n }),\n },\n }\n\n yield {\n type: 'progress',\n content: modifiedMessage,\n normalizedMessages,\n tools,\n }\n }\n }\n }\n }\n\n const normalizedMessages = normalizeMessages(messages)\n const lastMessage = last(messages)\n if (lastMessage?.type !== 'assistant') {\n throw new Error('Last message was not an assistant message')\n }\n\n // \uD83D\uDD27 CRITICAL FIX: Match original AgentTool interrupt handling pattern exactly\n if (\n lastMessage.message.content.some(\n _ => _.type === 'text' && _.text === INTERRUPT_MESSAGE,\n )\n ) {\n // Skip progress yield - only yield final result\n } else {\n const result = [\n toolUseCount === 1 ? '1 tool use' : `${toolUseCount} tool uses`,\n formatNumber(\n (lastMessage.message.usage.cache_creation_input_tokens ?? 0) +\n (lastMessage.message.usage.cache_read_input_tokens ?? 0) +\n lastMessage.message.usage.input_tokens +\n lastMessage.message.usage.output_tokens,\n ) + ' tokens',\n formatDuration(Date.now() - startTime),\n ]\n yield {\n type: 'progress',\n content: createAssistantMessage(\n `Task completed (${result.join(' \u00B7 ')})`,\n ),\n normalizedMessages,\n tools,\n }\n }\n\n // Output is an AssistantMessage, but since TaskTool is a tool, it needs\n // to serialize its response to UserMessage-compatible content.\n const data = lastMessage.message.content.filter(_ => _.type === 'text')\n yield {\n type: 'result',\n data,\n resultForAssistant: this.renderResultForAssistant(data),\n }\n },\n\n isReadOnly() {\n return true // for now...\n },\n isConcurrencySafe() {\n return true // Task tool supports concurrent execution in official implementation\n },\n async validateInput(input, context) {\n if (!input.description || typeof input.description !== 'string') {\n return {\n result: false,\n message: 'Description is required and must be a string',\n }\n }\n if (!input.prompt || typeof input.prompt !== 'string') {\n return {\n result: false,\n message: 'Prompt is required and must be a string',\n }\n }\n\n // Model validation - similar to Edit tool error handling\n if (input.model_name) {\n const modelManager = getModelManager()\n const availableModels = modelManager.getAllAvailableModelNames()\n\n if (!availableModels.includes(input.model_name)) {\n return {\n result: false,\n message: `Model '${input.model_name}' does not exist. Available models: ${availableModels.join(', ')}`,\n meta: {\n model_name: input.model_name,\n availableModels,\n },\n }\n }\n }\n\n // Validate subagent_type if provided\n if (input.subagent_type) {\n const availableTypes = await getAvailableAgentTypes()\n if (!availableTypes.includes(input.subagent_type)) {\n return {\n result: false,\n message: `Agent type '${input.subagent_type}' does not exist. Available types: ${availableTypes.join(', ')}`,\n meta: {\n subagent_type: input.subagent_type,\n availableTypes,\n },\n }\n }\n }\n\n return { result: true }\n },\n async isEnabled() {\n return true\n },\n userFacingName(input?: any) {\n // Return agent name with proper prefix\n const agentType = input?.subagent_type || 'general-purpose'\n return `agent-${agentType}`\n },\n needsPermissions() {\n return false\n },\n renderResultForAssistant(data: TextBlock[]) {\n return data\n .map(block => (block.type === 'text' ? block.text : ''))\n .join('\\n')\n },\n renderToolUseMessage(\n { description, prompt, model_name, subagent_type },\n { verbose },\n ) {\n if (!description || !prompt) return null\n\n const modelManager = getModelManager()\n const defaultTaskModel = modelManager.getModelName('task')\n const actualModel = model_name || defaultTaskModel\n const agentType = subagent_type || 'general-purpose'\n const promptPreview =\n prompt.length > 80 ? prompt.substring(0, 80) + '...' : prompt\n\n const theme = getTheme()\n\n if (verbose) {\n return (\n <Box flexDirection=\"column\">\n <Text>\n [{agentType}] {actualModel}: {description}\n </Text>\n <Box\n paddingLeft={2}\n borderLeftStyle=\"single\"\n borderLeftColor={theme.secondaryBorder}\n >\n <Text color={theme.secondaryText}>{promptPreview}</Text>\n </Box>\n </Box>\n )\n }\n\n // Simple display: agent type, model and description\n return `[${agentType}] ${actualModel}: ${description}`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(content) {\n const theme = getTheme()\n\n // Guard against undefined or null content\n if (!content) {\n return (\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color={theme.secondaryText}>Task completed</Text>\n </Box>\n )\n }\n\n if (Array.isArray(content)) {\n const textBlocks = content.filter(\n (block): block is { type: 'text'; text: string } =>\n block && block.type === 'text',\n )\n const totalLength = textBlocks.reduce(\n (sum, block) => sum + (block.text?.length || 0),\n 0,\n )\n // Use exact match for interrupt detection\n const isInterrupted = content.some(\n block =>\n block &&\n block.type === 'text' &&\n block.text === INTERRUPT_MESSAGE,\n )\n\n if (isInterrupted) {\n return (\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color={theme.error}>Interrupted by user</Text>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"column\">\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text>Task completed</Text>\n {textBlocks.length > 0 && (\n <Text color={theme.secondaryText}>\n {' '}\n ({totalLength} characters)\n </Text>\n )}\n </Box>\n </Box>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color={theme.secondaryText}>Task completed</Text>\n </Box>\n )\n },\n} satisfies Tool<typeof inputSchema, TextBlock[]>\n"],
5
+ "mappings": "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",
6
6
  "names": ["normalizedMessages"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/TaskTool/prompt.ts"],
4
- "sourcesContent": ["import { type Tool } from '@tool'\nimport { getTools, getReadOnlyTools } from '@tools'\nimport { TaskTool } from './TaskTool'\nimport { BashTool } from '@tools/BashTool/BashTool'\nimport { FileWriteTool } from '@tools/FileWriteTool/FileWriteTool'\nimport { FileEditTool } from '@tools/FileEditTool/FileEditTool'\nimport { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\nimport { GlobTool } from '@tools/GlobTool/GlobTool'\nimport { FileReadTool } from '@tools/FileReadTool/FileReadTool'\nimport { getModelManager } from '@utils/model'\nimport { getActiveAgents } from '@utils/agentLoader'\n\nexport async function getTaskTools(safeMode: boolean): Promise<Tool[]> {\n // No recursive tasks, yet..\n return (await (!safeMode ? getTools() : getReadOnlyTools())).filter(\n _ => _.name !== TaskTool.name,\n )\n}\n\nexport async function getPrompt(safeMode: boolean): Promise<string> {\n // Maintain compatibility with Claude Code `.claude` agent descriptions\n const agents = await getActiveAgents()\n \n // Format exactly as in original: (Tools: tool1, tool2)\n const agentDescriptions = agents.map(agent => {\n const toolsStr = Array.isArray(agent.tools) \n ? agent.tools.join(', ')\n : '*'\n return `- ${agent.agentType}: ${agent.whenToUse} (Tools: ${toolsStr})`\n }).join('\\n')\n \n // Keep the wording aligned so shared `.claude` agent packs behave identically\n return `Launch a new agent to handle complex, multi-step tasks autonomously. \n\nAvailable agent types and the tools they have access to:\n${agentDescriptions}\n\nWhen using the Task tool, you must specify a subagent_type parameter to select which agent type to use.\n\n\uD83D\uDEA8 CRITICAL: You MUST use the EXACT agent type name from the list above. Common mistakes to avoid:\n\nNAMING FORMAT:\n- \u2705 ALWAYS use hyphens (-): \"strategic-market-analyzer\", \"business-analyst\", \"qa-engineer\"\n- \u274C NEVER use underscores (_): \"strategic_market_analyzer\", \"business_analyst\"\n- \u274C NEVER use spaces: \"strategic market analyzer\", \"business analyst\"\n- \u274C NEVER invent names: \"researcher\", \"analyst\", \"data_analyst\"\n\nSELECTION RULES:\n1. For market/business analysis \u2192 use \"strategic-market-analyzer\" or \"business-analyst\"\n2. For data analysis \u2192 use \"data-scientist\"\n3. For general tasks \u2192 use \"general-purpose\"\n4. For code/QA tasks \u2192 use \"qa-engineer\" or \"code-reviewer\"\n\nIf unsure, use \"general-purpose\" - it has access to all tools.\n\nWhen to use the Agent tool:\n- When you are instructed to execute custom slash commands. Use the Agent tool with the slash command invocation as the entire prompt. The slash command can take arguments. For example: Task(description=\"Check the file\", prompt=\"/check-file path/to/file.py\")\n\nWhen NOT to use the Agent tool:\n- If you want to read a specific file path, use the ${FileReadTool.name} or ${GlobTool.name} tool instead of the Agent tool, to find the match more quickly\n- If you are searching for a specific class definition like \"class Foo\", use the ${GlobTool.name} tool instead, to find the match more quickly\n- If you are searching for code within a specific file or set of 2-3 files, use the ${FileReadTool.name} tool instead of the Agent tool, to find the match more quickly\n- Other tasks that are not related to the agent descriptions above\n\nUsage notes:\n1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses\n2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n3. Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.\n4. The agent's outputs should generally be trusted\n5. Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent\n6. If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.\n\nExample usage:\n\n<example>\n<scenario>Market research analysis with multiple files</scenario>\nuser: \"Analyze these 3 market research reports and summarize findings\"\nassistant: I'll use multiple subagents to analyze the reports in parallel.\n<uses Task tool>\nsubagent_type: \"strategic-market-analyzer\"\nprompt: \"Analyze market_report_1.md and provide key insights...\"\n</uses Task tool>\n<uses Task tool>\nsubagent_type: \"strategic-market-analyzer\"\nprompt: \"Analyze market_report_2.md and provide key insights...\"\n</uses Task tool>\n<uses Task tool>\nsubagent_type: \"business-analyst\"\nprompt: \"Analyze financial_report.md and provide key insights...\"\n</uses Task tool>\n</example>\n\n<example>\n<scenario>Code review after implementation</scenario>\nuser: \"Please write a function that checks if a number is prime\"\nassistant: First let me use the ${FileWriteTool.name} tool to write the function\n<writes code>\nassistant: Now let me use the code-reviewer agent to review the code\n<uses Task tool>\nsubagent_type: \"code-reviewer\"\nprompt: \"Review the isPrime function in utils.js for correctness and performance\"\n</uses Task tool>\n</example>\n\n<example>\n<scenario>Data analysis task</scenario>\nuser: \"Analyze the CSV data in sales.csv and find trends\"\nassistant: I'll use the data-scientist agent to analyze this data\n<uses Task tool>\nsubagent_type: \"data-scientist\"\nprompt: \"Analyze sales.csv and identify trends, patterns, and anomalies\"\n</uses Task tool>\n</example>\n\n\u274C WRONG EXAMPLES (DO NOT DO THIS):\n<wrong_example>\nsubagent_type: \"researcher\" \u2190 WRONG! This agent type doesn't exist\nsubagent_type: \"market_analyzer\" \u2190 WRONG! Uses underscore instead of hyphen\nsubagent_type: \"data analyst\" \u2190 WRONG! Uses space instead of hyphen\n</wrong_example>`\n}\n"],
5
- "mappings": "AACA,SAAS,UAAU,wBAAwB;AAC3C,SAAS,gBAAgB;AAEzB,SAAS,qBAAqB;AAG9B,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAE7B,SAAS,uBAAuB;AAEhC,eAAsB,aAAa,UAAoC;AAErE,UAAQ,OAAO,CAAC,WAAW,SAAS,IAAI,iBAAiB,IAAI;AAAA,IAC3D,OAAK,EAAE,SAAS,SAAS;AAAA,EAC3B;AACF;AAEA,eAAsB,UAAU,UAAoC;AAElE,QAAM,SAAS,MAAM,gBAAgB;AAGrC,QAAM,oBAAoB,OAAO,IAAI,WAAS;AAC5C,UAAM,WAAW,MAAM,QAAQ,MAAM,KAAK,IACtC,MAAM,MAAM,KAAK,IAAI,IACrB;AACJ,WAAO,KAAK,MAAM,SAAS,KAAK,MAAM,SAAS,YAAY,QAAQ;AAAA,EACrE,CAAC,EAAE,KAAK,IAAI;AAGZ,SAAO;AAAA;AAAA;AAAA,EAGP,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sDAwBmC,aAAa,IAAI,OAAO,SAAS,IAAI;AAAA,mFACR,SAAS,IAAI;AAAA,sFACV,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAkCrE,cAAc,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBpD;",
4
+ "sourcesContent": ["import { type Tool } from '@tool'\nimport { getTools, getReadOnlyTools } from '@tools'\nimport { TaskTool } from './TaskTool'\nimport { BashTool } from '@tools/BashTool/BashTool'\nimport { FileWriteTool } from '@tools/FileWriteTool/FileWriteTool'\nimport { FileEditTool } from '@tools/FileEditTool/FileEditTool'\nimport { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\nimport { GlobTool } from '@tools/GlobTool/GlobTool'\nimport { FileReadTool } from '@tools/FileReadTool/FileReadTool'\nimport { getModelManager } from '@utils/model'\nimport { getActiveAgents } from '@utils/agentLoader'\n\nexport async function getTaskTools(safeMode: boolean): Promise<Tool[]> {\n // No recursive tasks, yet..\n return (await (!safeMode ? getTools() : getReadOnlyTools())).filter(\n _ => _.name !== TaskTool.name,\n )\n}\n\nexport async function getPrompt(safeMode: boolean): Promise<string> {\n // Maintain compatibility with Claude Code `.claude` agent descriptions\n const agents = await getActiveAgents()\n\n // Format exactly as in original: (Tools: tool1, tool2)\n const agentDescriptions = agents\n .map(agent => {\n const toolsStr = Array.isArray(agent.tools) ? agent.tools.join(', ') : '*'\n return `- ${agent.agentType}: ${agent.whenToUse} (Tools: ${toolsStr})`\n })\n .join('\\n')\n\n // Keep the wording aligned so shared `.claude` agent packs behave identically\n return `Launch a new agent to handle complex, multi-step tasks autonomously. \n\nAvailable agent types and the tools they have access to:\n${agentDescriptions}\n\nWhen using the Task tool, you must specify a subagent_type parameter to select which agent type to use.\n\n\uD83D\uDEA8 CRITICAL: You MUST use the EXACT agent type name from the list above. Common mistakes to avoid:\n\nNAMING FORMAT:\n- \u2705 ALWAYS use hyphens (-): \"strategic-market-analyzer\", \"business-analyst\", \"qa-engineer\"\n- \u274C NEVER use underscores (_): \"strategic_market_analyzer\", \"business_analyst\"\n- \u274C NEVER use spaces: \"strategic market analyzer\", \"business analyst\"\n- \u274C NEVER invent names: \"researcher\", \"analyst\", \"data_analyst\"\n\nSELECTION RULES:\n1. For market/business analysis \u2192 use \"strategic-market-analyzer\" or \"business-analyst\"\n2. For data analysis \u2192 use \"data-scientist\"\n3. For general tasks \u2192 use \"general-purpose\"\n4. For code/QA tasks \u2192 use \"qa-engineer\" or \"code-reviewer\"\n\nIf unsure, use \"general-purpose\" - it has access to all tools.\n\nWhen to use the Agent tool:\n- When you are instructed to execute custom slash commands. Use the Agent tool with the slash command invocation as the entire prompt. The slash command can take arguments. For example: Task(description=\"Check the file\", prompt=\"/check-file path/to/file.py\")\n\nWhen NOT to use the Agent tool:\n- If you want to read a specific file path, use the ${FileReadTool.name} or ${GlobTool.name} tool instead of the Agent tool, to find the match more quickly\n- If you are searching for a specific class definition like \"class Foo\", use the ${GlobTool.name} tool instead, to find the match more quickly\n- If you are searching for code within a specific file or set of 2-3 files, use the ${FileReadTool.name} tool instead of the Agent tool, to find the match more quickly\n- Other tasks that are not related to the agent descriptions above\n\nUsage notes:\n1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses\n2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n3. Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.\n4. The agent's outputs should generally be trusted\n5. Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent\n6. If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.\n\nExample usage:\n\n<example>\n<scenario>Market research analysis with multiple files</scenario>\nuser: \"Analyze these 3 market research reports and summarize findings\"\nassistant: I'll use multiple subagents to analyze the reports in parallel.\n<uses Task tool>\nsubagent_type: \"strategic-market-analyzer\"\nprompt: \"Analyze market_report_1.md and provide key insights...\"\n</uses Task tool>\n<uses Task tool>\nsubagent_type: \"strategic-market-analyzer\"\nprompt: \"Analyze market_report_2.md and provide key insights...\"\n</uses Task tool>\n<uses Task tool>\nsubagent_type: \"business-analyst\"\nprompt: \"Analyze financial_report.md and provide key insights...\"\n</uses Task tool>\n</example>\n\n<example>\n<scenario>Code review after implementation</scenario>\nuser: \"Please write a function that checks if a number is prime\"\nassistant: First let me use the ${FileWriteTool.name} tool to write the function\n<writes code>\nassistant: Now let me use the code-reviewer agent to review the code\n<uses Task tool>\nsubagent_type: \"code-reviewer\"\nprompt: \"Review the isPrime function in utils.js for correctness and performance\"\n</uses Task tool>\n</example>\n\n<example>\n<scenario>Data analysis task</scenario>\nuser: \"Analyze the CSV data in sales.csv and find trends\"\nassistant: I'll use the data-scientist agent to analyze this data\n<uses Task tool>\nsubagent_type: \"data-scientist\"\nprompt: \"Analyze sales.csv and identify trends, patterns, and anomalies\"\n</uses Task tool>\n</example>\n\n\u274C WRONG EXAMPLES (DO NOT DO THIS):\n<wrong_example>\nsubagent_type: \"researcher\" \u2190 WRONG! This agent type doesn't exist\nsubagent_type: \"market_analyzer\" \u2190 WRONG! Uses underscore instead of hyphen\nsubagent_type: \"data analyst\" \u2190 WRONG! Uses space instead of hyphen\n</wrong_example>`\n}\n"],
5
+ "mappings": "AACA,SAAS,UAAU,wBAAwB;AAC3C,SAAS,gBAAgB;AAEzB,SAAS,qBAAqB;AAG9B,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAE7B,SAAS,uBAAuB;AAEhC,eAAsB,aAAa,UAAoC;AAErE,UAAQ,OAAO,CAAC,WAAW,SAAS,IAAI,iBAAiB,IAAI;AAAA,IAC3D,OAAK,EAAE,SAAS,SAAS;AAAA,EAC3B;AACF;AAEA,eAAsB,UAAU,UAAoC;AAElE,QAAM,SAAS,MAAM,gBAAgB;AAGrC,QAAM,oBAAoB,OACvB,IAAI,WAAS;AACZ,UAAM,WAAW,MAAM,QAAQ,MAAM,KAAK,IAAI,MAAM,MAAM,KAAK,IAAI,IAAI;AACvE,WAAO,KAAK,MAAM,SAAS,KAAK,MAAM,SAAS,YAAY,QAAQ;AAAA,EACrE,CAAC,EACA,KAAK,IAAI;AAGZ,SAAO;AAAA;AAAA;AAAA,EAGP,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sDAwBmC,aAAa,IAAI,OAAO,SAAS,IAAI;AAAA,mFACR,SAAS,IAAI;AAAA,sFACV,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAkCrE,cAAc,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBpD;",
6
6
  "names": []
7
7
  }
@@ -30,7 +30,12 @@ const ThinkTool = {
30
30
  return input.thought;
31
31
  },
32
32
  renderToolUseRejectedMessage() {
33
- return /* @__PURE__ */ React.createElement(MessageResponse, { children: /* @__PURE__ */ React.createElement(Text, { color: getTheme().error }, "Thought cancelled") });
33
+ return /* @__PURE__ */ React.createElement(
34
+ MessageResponse,
35
+ {
36
+ children: /* @__PURE__ */ React.createElement(Text, { color: getTheme().error }, "Thought cancelled")
37
+ }
38
+ );
34
39
  },
35
40
  renderResultForAssistant: () => "Your thought has been logged."
36
41
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/ThinkTool/ThinkTool.tsx"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport React from 'react'\nimport { Text } from 'ink'\nimport { Tool } from '@tool'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\nimport { MessageResponse } from '@components/MessageResponse'\nimport { USE_BEDROCK, USE_VERTEX } from '@utils/model'\n\nconst thinkToolSchema = z.object({\n thought: z.string().describe('Your thoughts.'),\n})\n\nexport const ThinkTool = {\n name: 'Think',\n userFacingName: () => 'Think',\n description: async () => DESCRIPTION,\n inputSchema: thinkToolSchema,\n isEnabled: async () => Boolean(process.env.THINK_TOOL),\n isReadOnly: () => true,\n isConcurrencySafe: () => true, // ThinkTool is read-only, safe for concurrent execution\n needsPermissions: () => false,\n prompt: async () => PROMPT,\n\n async *call(input, { messageId }) {\n \n\n yield {\n type: 'result',\n resultForAssistant: 'Your thought has been logged.',\n data: { thought: input.thought },\n }\n },\n\n // This is never called -- it's special-cased in AssistantToolUseMessage\n renderToolUseMessage(input) {\n return input.thought\n },\n\n renderToolUseRejectedMessage() {\n return (\n <MessageResponse children={<Text color={getTheme().error}>Thought cancelled</Text>} />\n )\n },\n\n renderResultForAssistant: () => 'Your thought has been logged.',\n} satisfies Tool<typeof thinkToolSchema>\n"],
5
- "mappings": "AAAA,SAAS,SAAS;AAClB,OAAO,WAAW;AAClB,SAAS,YAAY;AAErB,SAAS,aAAa,cAAc;AACpC,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAGhC,MAAM,kBAAkB,EAAE,OAAO;AAAA,EAC/B,SAAS,EAAE,OAAO,EAAE,SAAS,gBAAgB;AAC/C,CAAC;AAEM,MAAM,YAAY;AAAA,EACvB,MAAM;AAAA,EACN,gBAAgB,MAAM;AAAA,EACtB,aAAa,YAAY;AAAA,EACzB,aAAa;AAAA,EACb,WAAW,YAAY,QAAQ,QAAQ,IAAI,UAAU;AAAA,EACrD,YAAY,MAAM;AAAA,EAClB,mBAAmB,MAAM;AAAA;AAAA,EACzB,kBAAkB,MAAM;AAAA,EACxB,QAAQ,YAAY;AAAA,EAEpB,OAAO,KAAK,OAAO,EAAE,UAAU,GAAG;AAGhC,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,oBAAoB;AAAA,MACpB,MAAM,EAAE,SAAS,MAAM,QAAQ;AAAA,IACjC;AAAA,EACF;AAAA;AAAA,EAGA,qBAAqB,OAAO;AAC1B,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,+BAA+B;AAC7B,WACE,oCAAC,mBAAgB,UAAU,oCAAC,QAAK,OAAO,SAAS,EAAE,SAAO,mBAAiB,GAAS;AAAA,EAExF;AAAA,EAEA,0BAA0B,MAAM;AAClC;",
4
+ "sourcesContent": ["import { z } from 'zod'\nimport React from 'react'\nimport { Text } from 'ink'\nimport { Tool } from '@tool'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\nimport { MessageResponse } from '@components/MessageResponse'\nimport { USE_BEDROCK, USE_VERTEX } from '@utils/model'\n\nconst thinkToolSchema = z.object({\n thought: z.string().describe('Your thoughts.'),\n})\n\nexport const ThinkTool = {\n name: 'Think',\n userFacingName: () => 'Think',\n description: async () => DESCRIPTION,\n inputSchema: thinkToolSchema,\n isEnabled: async () => Boolean(process.env.THINK_TOOL),\n isReadOnly: () => true,\n isConcurrencySafe: () => true, // ThinkTool is read-only, safe for concurrent execution\n needsPermissions: () => false,\n prompt: async () => PROMPT,\n\n async *call(input, { messageId }) {\n yield {\n type: 'result',\n resultForAssistant: 'Your thought has been logged.',\n data: { thought: input.thought },\n }\n },\n\n // This is never called -- it's special-cased in AssistantToolUseMessage\n renderToolUseMessage(input) {\n return input.thought\n },\n\n renderToolUseRejectedMessage() {\n return (\n <MessageResponse\n children={<Text color={getTheme().error}>Thought cancelled</Text>}\n />\n )\n },\n\n renderResultForAssistant: () => 'Your thought has been logged.',\n} satisfies Tool<typeof thinkToolSchema>\n"],
5
+ "mappings": "AAAA,SAAS,SAAS;AAClB,OAAO,WAAW;AAClB,SAAS,YAAY;AAErB,SAAS,aAAa,cAAc;AACpC,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAGhC,MAAM,kBAAkB,EAAE,OAAO;AAAA,EAC/B,SAAS,EAAE,OAAO,EAAE,SAAS,gBAAgB;AAC/C,CAAC;AAEM,MAAM,YAAY;AAAA,EACvB,MAAM;AAAA,EACN,gBAAgB,MAAM;AAAA,EACtB,aAAa,YAAY;AAAA,EACzB,aAAa;AAAA,EACb,WAAW,YAAY,QAAQ,QAAQ,IAAI,UAAU;AAAA,EACrD,YAAY,MAAM;AAAA,EAClB,mBAAmB,MAAM;AAAA;AAAA,EACzB,kBAAkB,MAAM;AAAA,EACxB,QAAQ,YAAY;AAAA,EAEpB,OAAO,KAAK,OAAO,EAAE,UAAU,GAAG;AAChC,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,oBAAoB;AAAA,MACpB,MAAM,EAAE,SAAS,MAAM,QAAQ;AAAA,IACjC;AAAA,EACF;AAAA;AAAA,EAGA,qBAAqB,OAAO;AAC1B,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,+BAA+B;AAC7B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,oCAAC,QAAK,OAAO,SAAS,EAAE,SAAO,mBAAiB;AAAA;AAAA,IAC5D;AAAA,EAEJ;AAAA,EAEA,0BAA0B,MAAM;AAClC;",
6
6
  "names": []
7
7
  }
@@ -9,7 +9,9 @@ import { DESCRIPTION, PROMPT } from "./prompt.js";
9
9
  import { getTheme } from "../../utils/theme.js";
10
10
  const TodoItemSchema = z.object({
11
11
  content: z.string().min(1).describe("The task description or content"),
12
- activeForm: z.string().min(1).optional().describe('The present continuous form of the task (e.g., "Running tests" for "Run tests"). If not provided, will be auto-generated from content.'),
12
+ activeForm: z.string().min(1).optional().describe(
13
+ 'The present continuous form of the task (e.g., "Running tests" for "Run tests"). If not provided, will be auto-generated from content.'
14
+ ),
13
15
  status: z.enum(["pending", "in_progress", "completed"]).describe("Current status of the task"),
14
16
  priority: z.enum(["high", "medium", "low"]).describe("Priority level of the task"),
15
17
  id: z.string().min(1).describe("Unique identifier for the task")
@@ -138,17 +140,23 @@ const TodoWriteTool = {
138
140
  return /* @__PURE__ */ React.createElement(FallbackToolUseRejectedMessage, null);
139
141
  },
140
142
  renderToolResultMessage(output) {
143
+ if (output === void 0 || output === null) {
144
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: "#6B7280" }, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Text, { color: "#9CA3AF" }, "Todo operation completed")));
145
+ }
141
146
  const isError = typeof output === "string" && output.startsWith("Error");
142
147
  if (!isError && typeof output === "string") {
143
- const currentTodos = getTodos();
148
+ const currentTodos = getTodos() || [];
144
149
  if (currentTodos.length === 0) {
145
150
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: "#6B7280" }, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Text, { color: "#9CA3AF" }, "No todos currently")));
146
151
  }
147
152
  const sortedTodos = [...currentTodos].sort((a, b) => {
153
+ if (!a || !b) return 0;
148
154
  const order = ["completed", "in_progress", "pending"];
149
- return order.indexOf(a.status) - order.indexOf(b.status) || a.content.localeCompare(b.content);
155
+ return order.indexOf(a.status || "pending") - order.indexOf(b.status || "pending") || (a.content || "").localeCompare(b.content || "");
150
156
  });
151
- const nextPendingIndex = sortedTodos.findIndex((todo) => todo.status === "pending");
157
+ const nextPendingIndex = sortedTodos.findIndex(
158
+ (todo) => todo.status === "pending"
159
+ );
152
160
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: "100%" }, sortedTodos.map((todo, index) => {
153
161
  let checkbox;
154
162
  let textColor;
@@ -171,7 +179,23 @@ const TodoWriteTool = {
171
179
  textColor = "#9CA3AF";
172
180
  }
173
181
  }
174
- return /* @__PURE__ */ React.createElement(Box, { key: todo.id || index, flexDirection: "row", marginBottom: 0 }, /* @__PURE__ */ React.createElement(Text, { color: "#6B7280" }, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", flexGrow: 1 }, /* @__PURE__ */ React.createElement(Text, { color: textColor, bold: isBold, strikethrough: isStrikethrough }, checkbox), /* @__PURE__ */ React.createElement(Text, null, " "), /* @__PURE__ */ React.createElement(Text, { color: textColor, bold: isBold, strikethrough: isStrikethrough }, todo.content)));
182
+ return /* @__PURE__ */ React.createElement(Box, { key: todo.id || index, flexDirection: "row", marginBottom: 0 }, /* @__PURE__ */ React.createElement(Text, { color: "#6B7280" }, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", flexGrow: 1 }, /* @__PURE__ */ React.createElement(
183
+ Text,
184
+ {
185
+ color: textColor,
186
+ bold: isBold,
187
+ strikethrough: isStrikethrough
188
+ },
189
+ checkbox
190
+ ), /* @__PURE__ */ React.createElement(Text, null, " "), /* @__PURE__ */ React.createElement(
191
+ Text,
192
+ {
193
+ color: textColor,
194
+ bold: isBold,
195
+ strikethrough: isStrikethrough
196
+ },
197
+ todo.content
198
+ )));
175
199
  }));
176
200
  }
177
201
  return /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between", overflowX: "hidden", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: isError ? getTheme().error : getTheme().success }, "\xA0\xA0\u23BF \xA0", typeof output === "string" ? output : JSON.stringify(output))));
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/TodoWriteTool/TodoWriteTool.tsx"],
4
- "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { TodoItem as TodoItemComponent } from '@components/TodoItem'\nimport { Tool, ValidationResult } from '@tool'\nimport { setTodos, getTodos, TodoItem } from '@utils/todoStorage'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { startWatchingTodoFile } from '@services/fileFreshness'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst TodoItemSchema = z.object({\n content: z.string().min(1).describe('The task description or content'),\n activeForm: z.string().min(1).optional().describe('The present continuous form of the task (e.g., \"Running tests\" for \"Run tests\"). If not provided, will be auto-generated from content.'),\n status: z\n .enum(['pending', 'in_progress', 'completed'])\n .describe('Current status of the task'),\n priority: z\n .enum(['high', 'medium', 'low'])\n .describe('Priority level of the task'),\n id: z.string().min(1).describe('Unique identifier for the task'),\n})\n\nconst inputSchema = z.strictObject({\n todos: z.array(TodoItemSchema).describe('The updated todo list'),\n})\n\n/**\n * Auto-generates activeForm from content if not provided\n * Converts imperative form to present continuous\n * Examples: \"Run tests\" -> \"Running tests\", \"Fix bug\" -> \"Fixing bug\"\n */\nfunction generateActiveForm(content: string): string {\n const trimmed = content.trim()\n\n // Common verb patterns for imperative -> present continuous\n const patterns = [\n { regex: /^(Run|run)\\s+(.+)$/i, replacement: 'Running $2' },\n { regex: /^(Build|build)\\s+(.+)$/i, replacement: 'Building $2' },\n { regex: /^(Fix|fix)\\s+(.+)$/i, replacement: 'Fixing $2' },\n { regex: /^(Add|add)\\s+(.+)$/i, replacement: 'Adding $2' },\n { regex: /^(Create|create)\\s+(.+)$/i, replacement: 'Creating $2' },\n { regex: /^(Update|update)\\s+(.+)$/i, replacement: 'Updating $2' },\n { regex: /^(Delete|delete)\\s+(.+)$/i, replacement: 'Deleting $2' },\n { regex: /^(Test|test)\\s+(.+)$/i, replacement: 'Testing $2' },\n { regex: /^(Deploy|deploy)\\s+(.+)$/i, replacement: 'Deploying $2' },\n { regex: /^(Analyze|analyze)\\s+(.+)$/i, replacement: 'Analyzing $2' },\n { regex: /^(Review|review)\\s+(.+)$/i, replacement: 'Reviewing $2' },\n { regex: /^(Write|write)\\s+(.+)$/i, replacement: 'Writing $2' },\n ]\n\n for (const { regex, replacement } of patterns) {\n if (regex.test(trimmed)) {\n return trimmed.replace(regex, replacement)\n }\n }\n\n // Fallback: add \"Working on\" prefix\n return `Working on: ${trimmed}`\n}\n\nfunction validateTodos(todos: TodoItem[]): ValidationResult {\n // Check for duplicate IDs\n const ids = todos.map(todo => todo.id)\n const uniqueIds = new Set(ids)\n if (ids.length !== uniqueIds.size) {\n return {\n result: false,\n errorCode: 1,\n message: 'Duplicate todo IDs found',\n meta: {\n duplicateIds: ids.filter((id, index) => ids.indexOf(id) !== index),\n },\n }\n }\n\n // Check for multiple in_progress tasks\n const inProgressTasks = todos.filter(todo => todo.status === 'in_progress')\n if (inProgressTasks.length > 1) {\n return {\n result: false,\n errorCode: 2,\n message: 'Only one task can be in_progress at a time',\n meta: { inProgressTaskIds: inProgressTasks.map(t => t.id) },\n }\n }\n\n // Validate each todo\n for (const todo of todos) {\n if (!todo.content?.trim()) {\n return {\n result: false,\n errorCode: 3,\n message: `Todo with ID \"${todo.id}\" has empty content`,\n meta: { todoId: todo.id },\n }\n }\n if (!['pending', 'in_progress', 'completed'].includes(todo.status)) {\n return {\n result: false,\n errorCode: 4,\n message: `Invalid status \"${todo.status}\" for todo \"${todo.id}\"`,\n meta: { todoId: todo.id, invalidStatus: todo.status },\n }\n }\n if (!['high', 'medium', 'low'].includes(todo.priority)) {\n return {\n result: false,\n errorCode: 5,\n message: `Invalid priority \"${todo.priority}\" for todo \"${todo.id}\"`,\n meta: { todoId: todo.id, invalidPriority: todo.priority },\n }\n }\n }\n\n return { result: true }\n}\n\nfunction generateTodoSummary(todos: TodoItem[]): string {\n const stats = {\n total: todos.length,\n pending: todos.filter(t => t.status === 'pending').length,\n inProgress: todos.filter(t => t.status === 'in_progress').length,\n completed: todos.filter(t => t.status === 'completed').length,\n }\n\n // Enhanced summary with statistics\n let summary = `Updated ${stats.total} todo(s)`\n if (stats.total > 0) {\n summary += ` (${stats.pending} pending, ${stats.inProgress} in progress, ${stats.completed} completed)`\n }\n summary += '. Continue tracking your progress with the todo list.'\n\n return summary\n}\n\nexport const TodoWriteTool = {\n name: 'TodoWrite',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Update Todos'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // TodoWrite modifies state, not safe for concurrent execution\n },\n needsPermissions() {\n return false\n },\n renderResultForAssistant(result) {\n // Match official implementation - return static confirmation message\n return 'Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable'\n },\n renderToolUseMessage(input, { verbose }) {\n // Show a simple confirmation message when the tool is being used\n return '{ params.todo }'\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output) {\n const isError = typeof output === 'string' && output.startsWith('Error')\n\n // For non-error output, get current todos from storage and render them\n if (!isError && typeof output === 'string') {\n const currentTodos = getTodos()\n \n if (currentTodos.length === 0) {\n return (\n <Box flexDirection=\"column\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text color=\"#6B7280\">&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color=\"#9CA3AF\">No todos currently</Text>\n </Box>\n </Box>\n )\n }\n\n // Sort: [completed, in_progress, pending]\n const sortedTodos = [...currentTodos].sort((a, b) => {\n const order = ['completed', 'in_progress', 'pending']\n return (\n order.indexOf(a.status) - order.indexOf(b.status) ||\n a.content.localeCompare(b.content)\n )\n })\n\n // Find the next pending task (first pending task after sorting)\n const nextPendingIndex = sortedTodos.findIndex(todo => todo.status === 'pending')\n\n return (\n <Box flexDirection=\"column\" width=\"100%\">\n {sortedTodos.map((todo: TodoItem, index: number) => {\n // Determine checkbox symbol and colors\n let checkbox: string\n let textColor: string\n let isBold = false\n let isStrikethrough = false\n\n if (todo.status === 'completed') {\n checkbox = '\u2612'\n textColor = '#6B7280' // Professional gray for completed\n isStrikethrough = true\n } else if (todo.status === 'in_progress') {\n checkbox = '\u2610'\n textColor = '#10B981' // Professional green for in progress\n isBold = true\n } else if (todo.status === 'pending') {\n checkbox = '\u2610'\n // Only the FIRST pending task gets purple highlight\n if (index === nextPendingIndex) {\n textColor = '#8B5CF6' // Professional purple for next pending\n isBold = true\n } else {\n textColor = '#9CA3AF' // Muted gray for other pending\n }\n }\n\n return (\n <Box key={todo.id || index} flexDirection=\"row\" marginBottom={0}>\n <Text color=\"#6B7280\">&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Box flexDirection=\"row\" flexGrow={1}>\n <Text color={textColor} bold={isBold} strikethrough={isStrikethrough}>\n {checkbox}\n </Text>\n <Text> </Text>\n <Text color={textColor} bold={isBold} strikethrough={isStrikethrough}>\n {todo.content}\n </Text>\n </Box>\n </Box>\n )\n })}\n </Box>\n )\n }\n\n // Fallback to simple text rendering for errors or string output\n return (\n <Box justifyContent=\"space-between\" overflowX=\"hidden\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text color={isError ? getTheme().error : getTheme().success}>\n &nbsp;&nbsp;\u23BF &nbsp;\n {typeof output === 'string' ? output : JSON.stringify(output)}\n </Text>\n </Box>\n </Box>\n )\n },\n async validateInput({ todos }: z.infer<typeof inputSchema>) {\n // Type assertion to ensure todos match TodoItem[] interface\n const todoItems = todos as TodoItem[]\n const validation = validateTodos(todoItems)\n if (!validation.result) {\n return validation\n }\n return { result: true }\n },\n async *call({ todos }: z.infer<typeof inputSchema>, context) {\n try {\n // Get agent ID from context\n const agentId = context?.agentId\n\n // Start watching todo file for this agent if not already watching\n if (agentId) {\n startWatchingTodoFile(agentId)\n }\n\n // Store previous todos for comparison (agent-scoped)\n const previousTodos = getTodos(agentId)\n\n // Type assertion to ensure todos match TodoItem[] interface\n // Auto-generate activeForm for todos that don't have it\n const todoItems = todos.map(todo => ({\n ...todo,\n activeForm: todo.activeForm || generateActiveForm(todo.content),\n })) as TodoItem[]\n\n // Note: Validation already done in validateInput, no need for duplicate validation\n // This eliminates the double validation issue\n\n // Update the todos in storage (agent-scoped)\n setTodos(todoItems, agentId)\n\n // Emit todo change event for system reminders (optimized - only if todos actually changed)\n const hasChanged =\n JSON.stringify(previousTodos) !== JSON.stringify(todoItems)\n if (hasChanged) {\n emitReminderEvent('todo:changed', {\n previousTodos,\n newTodos: todoItems,\n timestamp: Date.now(),\n agentId: agentId || 'default',\n changeType:\n todoItems.length > previousTodos.length\n ? 'added'\n : todoItems.length < previousTodos.length\n ? 'removed'\n : 'modified',\n })\n }\n\n // Generate enhanced summary\n const summary = generateTodoSummary(todoItems)\n\n // Enhanced result data for rendering\n const resultData = {\n oldTodos: previousTodos,\n newTodos: todoItems,\n summary,\n }\n\n yield {\n type: 'result',\n data: summary, // Return string to satisfy interface\n resultForAssistant: summary,\n // Store todo data in a way accessible to the renderer\n // We'll modify the renderToolResultMessage to get todos from storage\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n const errorResult = `Error updating todos: ${errorMessage}`\n\n // Emit error event for system monitoring\n emitReminderEvent('todo:error', {\n error: errorMessage,\n timestamp: Date.now(),\n agentId: context?.agentId || 'default',\n context: 'TodoWriteTool.call',\n })\n\n yield {\n type: 'result',\n data: errorResult,\n resultForAssistant: errorResult,\n }\n }\n },\n} satisfies Tool<typeof inputSchema, string>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { TodoItem as TodoItemComponent } from '@components/TodoItem'\nimport { Tool, ValidationResult } from '@tool'\nimport { setTodos, getTodos, TodoItem } from '@utils/todoStorage'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { startWatchingTodoFile } from '@services/fileFreshness'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst TodoItemSchema = z.object({\n content: z.string().min(1).describe('The task description or content'),\n activeForm: z\n .string()\n .min(1)\n .optional()\n .describe(\n 'The present continuous form of the task (e.g., \"Running tests\" for \"Run tests\"). If not provided, will be auto-generated from content.',\n ),\n status: z\n .enum(['pending', 'in_progress', 'completed'])\n .describe('Current status of the task'),\n priority: z\n .enum(['high', 'medium', 'low'])\n .describe('Priority level of the task'),\n id: z.string().min(1).describe('Unique identifier for the task'),\n})\n\nconst inputSchema = z.strictObject({\n todos: z.array(TodoItemSchema).describe('The updated todo list'),\n})\n\n/**\n * Auto-generates activeForm from content if not provided\n * Converts imperative form to present continuous\n * Examples: \"Run tests\" -> \"Running tests\", \"Fix bug\" -> \"Fixing bug\"\n */\nfunction generateActiveForm(content: string): string {\n const trimmed = content.trim()\n\n // Common verb patterns for imperative -> present continuous\n const patterns = [\n { regex: /^(Run|run)\\s+(.+)$/i, replacement: 'Running $2' },\n { regex: /^(Build|build)\\s+(.+)$/i, replacement: 'Building $2' },\n { regex: /^(Fix|fix)\\s+(.+)$/i, replacement: 'Fixing $2' },\n { regex: /^(Add|add)\\s+(.+)$/i, replacement: 'Adding $2' },\n { regex: /^(Create|create)\\s+(.+)$/i, replacement: 'Creating $2' },\n { regex: /^(Update|update)\\s+(.+)$/i, replacement: 'Updating $2' },\n { regex: /^(Delete|delete)\\s+(.+)$/i, replacement: 'Deleting $2' },\n { regex: /^(Test|test)\\s+(.+)$/i, replacement: 'Testing $2' },\n { regex: /^(Deploy|deploy)\\s+(.+)$/i, replacement: 'Deploying $2' },\n { regex: /^(Analyze|analyze)\\s+(.+)$/i, replacement: 'Analyzing $2' },\n { regex: /^(Review|review)\\s+(.+)$/i, replacement: 'Reviewing $2' },\n { regex: /^(Write|write)\\s+(.+)$/i, replacement: 'Writing $2' },\n ]\n\n for (const { regex, replacement } of patterns) {\n if (regex.test(trimmed)) {\n return trimmed.replace(regex, replacement)\n }\n }\n\n // Fallback: add \"Working on\" prefix\n return `Working on: ${trimmed}`\n}\n\nfunction validateTodos(todos: TodoItem[]): ValidationResult {\n // Check for duplicate IDs\n const ids = todos.map(todo => todo.id)\n const uniqueIds = new Set(ids)\n if (ids.length !== uniqueIds.size) {\n return {\n result: false,\n errorCode: 1,\n message: 'Duplicate todo IDs found',\n meta: {\n duplicateIds: ids.filter((id, index) => ids.indexOf(id) !== index),\n },\n }\n }\n\n // Check for multiple in_progress tasks\n const inProgressTasks = todos.filter(todo => todo.status === 'in_progress')\n if (inProgressTasks.length > 1) {\n return {\n result: false,\n errorCode: 2,\n message: 'Only one task can be in_progress at a time',\n meta: { inProgressTaskIds: inProgressTasks.map(t => t.id) },\n }\n }\n\n // Validate each todo\n for (const todo of todos) {\n if (!todo.content?.trim()) {\n return {\n result: false,\n errorCode: 3,\n message: `Todo with ID \"${todo.id}\" has empty content`,\n meta: { todoId: todo.id },\n }\n }\n if (!['pending', 'in_progress', 'completed'].includes(todo.status)) {\n return {\n result: false,\n errorCode: 4,\n message: `Invalid status \"${todo.status}\" for todo \"${todo.id}\"`,\n meta: { todoId: todo.id, invalidStatus: todo.status },\n }\n }\n if (!['high', 'medium', 'low'].includes(todo.priority)) {\n return {\n result: false,\n errorCode: 5,\n message: `Invalid priority \"${todo.priority}\" for todo \"${todo.id}\"`,\n meta: { todoId: todo.id, invalidPriority: todo.priority },\n }\n }\n }\n\n return { result: true }\n}\n\nfunction generateTodoSummary(todos: TodoItem[]): string {\n const stats = {\n total: todos.length,\n pending: todos.filter(t => t.status === 'pending').length,\n inProgress: todos.filter(t => t.status === 'in_progress').length,\n completed: todos.filter(t => t.status === 'completed').length,\n }\n\n // Enhanced summary with statistics\n let summary = `Updated ${stats.total} todo(s)`\n if (stats.total > 0) {\n summary += ` (${stats.pending} pending, ${stats.inProgress} in progress, ${stats.completed} completed)`\n }\n summary += '. Continue tracking your progress with the todo list.'\n\n return summary\n}\n\nexport const TodoWriteTool = {\n name: 'TodoWrite',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Update Todos'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // TodoWrite modifies state, not safe for concurrent execution\n },\n needsPermissions() {\n return false\n },\n renderResultForAssistant(result) {\n // Match official implementation - return static confirmation message\n return 'Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable'\n },\n renderToolUseMessage(input, { verbose }) {\n // Show a simple confirmation message when the tool is being used\n return '{ params.todo }'\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output) {\n // Guard against undefined or null output\n if (output === undefined || output === null) {\n return (\n <Box flexDirection=\"column\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text color=\"#6B7280\">&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color=\"#9CA3AF\">Todo operation completed</Text>\n </Box>\n </Box>\n )\n }\n\n const isError = typeof output === 'string' && output.startsWith('Error')\n\n // For non-error output, get current todos from storage and render them\n if (!isError && typeof output === 'string') {\n const currentTodos = getTodos() || []\n\n if (currentTodos.length === 0) {\n return (\n <Box flexDirection=\"column\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text color=\"#6B7280\">&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text color=\"#9CA3AF\">No todos currently</Text>\n </Box>\n </Box>\n )\n }\n\n // Sort: [completed, in_progress, pending]\n const sortedTodos = [...currentTodos].sort((a, b) => {\n if (!a || !b) return 0\n const order = ['completed', 'in_progress', 'pending']\n return (\n order.indexOf(a.status || 'pending') -\n order.indexOf(b.status || 'pending') ||\n (a.content || '').localeCompare(b.content || '')\n )\n })\n\n // Find the next pending task (first pending task after sorting)\n const nextPendingIndex = sortedTodos.findIndex(\n todo => todo.status === 'pending',\n )\n\n return (\n <Box flexDirection=\"column\" width=\"100%\">\n {sortedTodos.map((todo: TodoItem, index: number) => {\n // Determine checkbox symbol and colors\n let checkbox: string\n let textColor: string\n let isBold = false\n let isStrikethrough = false\n\n if (todo.status === 'completed') {\n checkbox = '\u2612'\n textColor = '#6B7280' // Professional gray for completed\n isStrikethrough = true\n } else if (todo.status === 'in_progress') {\n checkbox = '\u2610'\n textColor = '#10B981' // Professional green for in progress\n isBold = true\n } else if (todo.status === 'pending') {\n checkbox = '\u2610'\n // Only the FIRST pending task gets purple highlight\n if (index === nextPendingIndex) {\n textColor = '#8B5CF6' // Professional purple for next pending\n isBold = true\n } else {\n textColor = '#9CA3AF' // Muted gray for other pending\n }\n }\n\n return (\n <Box key={todo.id || index} flexDirection=\"row\" marginBottom={0}>\n <Text color=\"#6B7280\">&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Box flexDirection=\"row\" flexGrow={1}>\n <Text\n color={textColor}\n bold={isBold}\n strikethrough={isStrikethrough}\n >\n {checkbox}\n </Text>\n <Text> </Text>\n <Text\n color={textColor}\n bold={isBold}\n strikethrough={isStrikethrough}\n >\n {todo.content}\n </Text>\n </Box>\n </Box>\n )\n })}\n </Box>\n )\n }\n\n // Fallback to simple text rendering for errors or string output\n return (\n <Box justifyContent=\"space-between\" overflowX=\"hidden\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text color={isError ? getTheme().error : getTheme().success}>\n &nbsp;&nbsp;\u23BF &nbsp;\n {typeof output === 'string' ? output : JSON.stringify(output)}\n </Text>\n </Box>\n </Box>\n )\n },\n async validateInput({ todos }: z.infer<typeof inputSchema>) {\n // Type assertion to ensure todos match TodoItem[] interface\n const todoItems = todos as TodoItem[]\n const validation = validateTodos(todoItems)\n if (!validation.result) {\n return validation\n }\n return { result: true }\n },\n async *call({ todos }: z.infer<typeof inputSchema>, context) {\n try {\n // Get agent ID from context\n const agentId = context?.agentId\n\n // Start watching todo file for this agent if not already watching\n if (agentId) {\n startWatchingTodoFile(agentId)\n }\n\n // Store previous todos for comparison (agent-scoped)\n const previousTodos = getTodos(agentId)\n\n // Type assertion to ensure todos match TodoItem[] interface\n // Auto-generate activeForm for todos that don't have it\n const todoItems = todos.map(todo => ({\n ...todo,\n activeForm: todo.activeForm || generateActiveForm(todo.content),\n })) as TodoItem[]\n\n // Note: Validation already done in validateInput, no need for duplicate validation\n // This eliminates the double validation issue\n\n // Update the todos in storage (agent-scoped)\n setTodos(todoItems, agentId)\n\n // Emit todo change event for system reminders (optimized - only if todos actually changed)\n const hasChanged =\n JSON.stringify(previousTodos) !== JSON.stringify(todoItems)\n if (hasChanged) {\n emitReminderEvent('todo:changed', {\n previousTodos,\n newTodos: todoItems,\n timestamp: Date.now(),\n agentId: agentId || 'default',\n changeType:\n todoItems.length > previousTodos.length\n ? 'added'\n : todoItems.length < previousTodos.length\n ? 'removed'\n : 'modified',\n })\n }\n\n // Generate enhanced summary\n const summary = generateTodoSummary(todoItems)\n\n // Enhanced result data for rendering\n const resultData = {\n oldTodos: previousTodos,\n newTodos: todoItems,\n summary,\n }\n\n yield {\n type: 'result',\n data: summary, // Return string to satisfy interface\n resultForAssistant: summary,\n // Store todo data in a way accessible to the renderer\n // We'll modify the renderToolResultMessage to get todos from storage\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n const errorResult = `Error updating todos: ${errorMessage}`\n\n // Emit error event for system monitoring\n emitReminderEvent('todo:error', {\n error: errorMessage,\n timestamp: Date.now(),\n agentId: context?.agentId || 'default',\n context: 'TodoWriteTool.call',\n })\n\n yield {\n type: 'result',\n data: errorResult,\n resultForAssistant: errorResult,\n }\n }\n },\n} satisfies Tool<typeof inputSchema, string>\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }