@within-7/minto 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/dist/commands/agents/AgentsCommand.js +22 -24
  2. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  3. package/dist/commands/context.js +2 -1
  4. package/dist/commands/context.js.map +2 -2
  5. package/dist/commands/export.js +2 -1
  6. package/dist/commands/export.js.map +2 -2
  7. package/dist/commands/mcp-interactive.js +7 -6
  8. package/dist/commands/mcp-interactive.js.map +2 -2
  9. package/dist/commands/model.js +3 -2
  10. package/dist/commands/model.js.map +2 -2
  11. package/dist/commands/permissions.js +4 -3
  12. package/dist/commands/permissions.js.map +2 -2
  13. package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
  14. package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
  15. package/dist/commands/plugin/ConfirmDialog.js +2 -1
  16. package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
  17. package/dist/commands/plugin/ErrorView.js +2 -1
  18. package/dist/commands/plugin/ErrorView.js.map +2 -2
  19. package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
  20. package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
  21. package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
  22. package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
  23. package/dist/commands/plugin/MainMenu.js +2 -1
  24. package/dist/commands/plugin/MainMenu.js.map +2 -2
  25. package/dist/commands/plugin/MarketplaceManager.js +5 -4
  26. package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
  27. package/dist/commands/plugin/MarketplaceSelector.js +4 -3
  28. package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
  29. package/dist/commands/plugin/PlaceholderScreen.js +3 -2
  30. package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
  31. package/dist/commands/plugin/PluginBrowser.js +6 -5
  32. package/dist/commands/plugin/PluginBrowser.js.map +2 -2
  33. package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
  34. package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
  35. package/dist/commands/plugin/PluginDetailsManage.js +4 -3
  36. package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
  37. package/dist/commands/plugin.js +16 -15
  38. package/dist/commands/plugin.js.map +2 -2
  39. package/dist/commands/sandbox.js +4 -3
  40. package/dist/commands/sandbox.js.map +2 -2
  41. package/dist/commands/setup.js +2 -1
  42. package/dist/commands/setup.js.map +2 -2
  43. package/dist/commands/status.js +2 -1
  44. package/dist/commands/status.js.map +2 -2
  45. package/dist/commands/undo.js +245 -0
  46. package/dist/commands/undo.js.map +7 -0
  47. package/dist/commands.js +2 -0
  48. package/dist/commands.js.map +2 -2
  49. package/dist/components/AgentThinkingBlock.js +1 -1
  50. package/dist/components/AgentThinkingBlock.js.map +2 -2
  51. package/dist/components/AsciiLogo.js +7 -8
  52. package/dist/components/AsciiLogo.js.map +2 -2
  53. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
  54. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
  55. package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
  56. package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
  57. package/dist/components/CollapsibleHint.js +2 -1
  58. package/dist/components/CollapsibleHint.js.map +2 -2
  59. package/dist/components/Config.js +3 -2
  60. package/dist/components/Config.js.map +2 -2
  61. package/dist/components/ConsoleOAuthFlow.js +2 -1
  62. package/dist/components/ConsoleOAuthFlow.js.map +2 -2
  63. package/dist/components/Cost.js +2 -1
  64. package/dist/components/Cost.js.map +2 -2
  65. package/dist/components/HeaderBar.js +13 -8
  66. package/dist/components/HeaderBar.js.map +2 -2
  67. package/dist/components/HistorySearchOverlay.js +4 -3
  68. package/dist/components/HistorySearchOverlay.js.map +2 -2
  69. package/dist/components/HotkeyHelpPanel.js +8 -11
  70. package/dist/components/HotkeyHelpPanel.js.map +2 -2
  71. package/dist/components/InvalidConfigDialog.js +2 -1
  72. package/dist/components/InvalidConfigDialog.js.map +2 -2
  73. package/dist/components/Logo.js +23 -67
  74. package/dist/components/Logo.js.map +2 -2
  75. package/dist/components/MCPServerApprovalDialog.js +2 -1
  76. package/dist/components/MCPServerApprovalDialog.js.map +2 -2
  77. package/dist/components/MCPServerDialogCopy.js +2 -1
  78. package/dist/components/MCPServerDialogCopy.js.map +2 -2
  79. package/dist/components/MCPServerMultiselectDialog.js +2 -1
  80. package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
  81. package/dist/components/MessageSelector.js +4 -3
  82. package/dist/components/MessageSelector.js.map +2 -2
  83. package/dist/components/ModeIndicator.js +2 -1
  84. package/dist/components/ModeIndicator.js.map +2 -2
  85. package/dist/components/ModelConfig.js +4 -3
  86. package/dist/components/ModelConfig.js.map +2 -2
  87. package/dist/components/ModelListManager.js +4 -3
  88. package/dist/components/ModelListManager.js.map +2 -2
  89. package/dist/components/ModelSelector/ModelSelector.js +26 -13
  90. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  91. package/dist/components/Onboarding.js +3 -2
  92. package/dist/components/Onboarding.js.map +2 -2
  93. package/dist/components/OperationSummary.js +130 -0
  94. package/dist/components/OperationSummary.js.map +7 -0
  95. package/dist/components/PromptInput.js +88 -75
  96. package/dist/components/PromptInput.js.map +2 -2
  97. package/dist/components/SensitiveFileWarning.js +31 -0
  98. package/dist/components/SensitiveFileWarning.js.map +7 -0
  99. package/dist/components/Spinner.js +71 -22
  100. package/dist/components/Spinner.js.map +2 -2
  101. package/dist/components/StructuredDiff.js +6 -8
  102. package/dist/components/StructuredDiff.js.map +2 -2
  103. package/dist/components/SubagentBlock.js +4 -2
  104. package/dist/components/SubagentBlock.js.map +2 -2
  105. package/dist/components/SubagentProgress.js +7 -4
  106. package/dist/components/SubagentProgress.js.map +2 -2
  107. package/dist/components/TaskCard.js +14 -11
  108. package/dist/components/TaskCard.js.map +2 -2
  109. package/dist/components/TextInput.js +9 -1
  110. package/dist/components/TextInput.js.map +2 -2
  111. package/dist/components/TodoPanel.js +44 -26
  112. package/dist/components/TodoPanel.js.map +2 -2
  113. package/dist/components/ToolUseLoader.js +2 -2
  114. package/dist/components/ToolUseLoader.js.map +2 -2
  115. package/dist/components/TreeConnector.js +4 -3
  116. package/dist/components/TreeConnector.js.map +2 -2
  117. package/dist/components/TrustDialog.js +2 -1
  118. package/dist/components/TrustDialog.js.map +2 -2
  119. package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
  120. package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
  121. package/dist/components/messages/AssistantTextMessage.js +17 -9
  122. package/dist/components/messages/AssistantTextMessage.js.map +2 -2
  123. package/dist/components/messages/AssistantToolUseMessage.js +8 -4
  124. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  125. package/dist/components/messages/GroupRenderer.js +2 -1
  126. package/dist/components/messages/GroupRenderer.js.map +2 -2
  127. package/dist/components/messages/NestedTasksPreview.js +13 -1
  128. package/dist/components/messages/NestedTasksPreview.js.map +2 -2
  129. package/dist/components/messages/ParallelTasksGroupView.js +4 -3
  130. package/dist/components/messages/ParallelTasksGroupView.js.map +2 -2
  131. package/dist/components/messages/TaskInModuleView.js +35 -15
  132. package/dist/components/messages/TaskInModuleView.js.map +2 -2
  133. package/dist/components/messages/TaskOutputContent.js +9 -6
  134. package/dist/components/messages/TaskOutputContent.js.map +2 -2
  135. package/dist/components/messages/UserPromptMessage.js +2 -2
  136. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  137. package/dist/constants/colors.js +90 -72
  138. package/dist/constants/colors.js.map +2 -2
  139. package/dist/constants/toolInputExamples.js +84 -0
  140. package/dist/constants/toolInputExamples.js.map +7 -0
  141. package/dist/core/backupManager.js +321 -0
  142. package/dist/core/backupManager.js.map +7 -0
  143. package/dist/core/costTracker.js +9 -18
  144. package/dist/core/costTracker.js.map +2 -2
  145. package/dist/core/gitAutoCommit.js +287 -0
  146. package/dist/core/gitAutoCommit.js.map +7 -0
  147. package/dist/core/index.js +3 -0
  148. package/dist/core/index.js.map +2 -2
  149. package/dist/core/operationTracker.js +212 -0
  150. package/dist/core/operationTracker.js.map +7 -0
  151. package/dist/core/permissions/rules/allowedToolsRule.js +1 -1
  152. package/dist/core/permissions/rules/allowedToolsRule.js.map +2 -2
  153. package/dist/core/permissions/rules/autoEscalationRule.js +5 -0
  154. package/dist/core/permissions/rules/autoEscalationRule.js.map +2 -2
  155. package/dist/core/permissions/rules/projectBoundaryRule.js +5 -0
  156. package/dist/core/permissions/rules/projectBoundaryRule.js.map +2 -2
  157. package/dist/core/permissions/rules/sensitivePathsRule.js +5 -0
  158. package/dist/core/permissions/rules/sensitivePathsRule.js.map +2 -2
  159. package/dist/core/tokenStats.js +9 -0
  160. package/dist/core/tokenStats.js.map +7 -0
  161. package/dist/core/tokenStatsManager.js +331 -0
  162. package/dist/core/tokenStatsManager.js.map +7 -0
  163. package/dist/entrypoints/cli.js +115 -87
  164. package/dist/entrypoints/cli.js.map +2 -2
  165. package/dist/hooks/useAgentTokenStats.js +72 -0
  166. package/dist/hooks/useAgentTokenStats.js.map +7 -0
  167. package/dist/hooks/useAgentTranscripts.js +30 -6
  168. package/dist/hooks/useAgentTranscripts.js.map +2 -2
  169. package/dist/hooks/useLogMessages.js +12 -1
  170. package/dist/hooks/useLogMessages.js.map +2 -2
  171. package/dist/i18n/locales/en.js +6 -5
  172. package/dist/i18n/locales/en.js.map +2 -2
  173. package/dist/i18n/locales/zh-CN.js +6 -5
  174. package/dist/i18n/locales/zh-CN.js.map +2 -2
  175. package/dist/i18n/types.js.map +1 -1
  176. package/dist/permissions.js +28 -1
  177. package/dist/permissions.js.map +2 -2
  178. package/dist/query.js +78 -4
  179. package/dist/query.js.map +3 -3
  180. package/dist/screens/REPL.js +23 -3
  181. package/dist/screens/REPL.js.map +2 -2
  182. package/dist/services/claude.js +54 -3
  183. package/dist/services/claude.js.map +2 -2
  184. package/dist/services/intelligentCompactor.js +1 -1
  185. package/dist/services/intelligentCompactor.js.map +2 -2
  186. package/dist/services/mcpClient.js +81 -25
  187. package/dist/services/mcpClient.js.map +2 -2
  188. package/dist/services/sandbox/filesystemBoundary.js +58 -17
  189. package/dist/services/sandbox/filesystemBoundary.js.map +2 -2
  190. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -2
  191. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  192. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +2 -1
  193. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
  194. package/dist/tools/BashTool/BashTool.js +22 -3
  195. package/dist/tools/BashTool/BashTool.js.map +2 -2
  196. package/dist/tools/BashTool/prompt.js +178 -34
  197. package/dist/tools/BashTool/prompt.js.map +2 -2
  198. package/dist/tools/FileEditTool/prompt.js +6 -3
  199. package/dist/tools/FileEditTool/prompt.js.map +2 -2
  200. package/dist/tools/FileWriteTool/prompt.js +4 -2
  201. package/dist/tools/FileWriteTool/prompt.js.map +2 -2
  202. package/dist/tools/MultiEditTool/prompt.js +5 -3
  203. package/dist/tools/MultiEditTool/prompt.js.map +2 -2
  204. package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -1
  205. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  206. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +3 -2
  207. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
  208. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +3 -2
  209. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
  210. package/dist/tools/PlanModeTool/prompt.js +1 -1
  211. package/dist/tools/PlanModeTool/prompt.js.map +1 -1
  212. package/dist/tools/SkillTool/SkillTool.js +4 -3
  213. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  214. package/dist/tools/SkillTool/prompt.js +1 -1
  215. package/dist/tools/SkillTool/prompt.js.map +1 -1
  216. package/dist/tools/TaskOutputTool/TaskOutputTool.js +3 -2
  217. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +2 -2
  218. package/dist/tools/TaskTool/TaskTool.js +8 -0
  219. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  220. package/dist/utils/CircuitBreaker.js +242 -0
  221. package/dist/utils/CircuitBreaker.js.map +7 -0
  222. package/dist/utils/ask.js +2 -0
  223. package/dist/utils/ask.js.map +2 -2
  224. package/dist/utils/config.js +47 -5
  225. package/dist/utils/config.js.map +2 -2
  226. package/dist/utils/credentials/CredentialStore.js +1 -0
  227. package/dist/utils/credentials/CredentialStore.js.map +7 -0
  228. package/dist/utils/credentials/EncryptedFileStore.js +157 -0
  229. package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
  230. package/dist/utils/credentials/index.js +37 -0
  231. package/dist/utils/credentials/index.js.map +7 -0
  232. package/dist/utils/credentials/migration.js +82 -0
  233. package/dist/utils/credentials/migration.js.map +7 -0
  234. package/dist/utils/markdown.js +13 -1
  235. package/dist/utils/markdown.js.map +2 -2
  236. package/dist/utils/permissions/filesystem.js +5 -1
  237. package/dist/utils/permissions/filesystem.js.map +2 -2
  238. package/dist/utils/safePath.js +132 -0
  239. package/dist/utils/safePath.js.map +7 -0
  240. package/dist/utils/sensitiveFiles.js +125 -0
  241. package/dist/utils/sensitiveFiles.js.map +7 -0
  242. package/dist/utils/taskDisplayUtils.js +9 -9
  243. package/dist/utils/taskDisplayUtils.js.map +2 -2
  244. package/dist/utils/theme.js +6 -6
  245. package/dist/utils/theme.js.map +1 -1
  246. package/dist/utils/toolRiskClassification.js +207 -0
  247. package/dist/utils/toolRiskClassification.js.map +7 -0
  248. package/dist/utils/tooling/safeRender.js +5 -4
  249. package/dist/utils/tooling/safeRender.js.map +2 -2
  250. package/dist/version.js +2 -2
  251. package/dist/version.js.map +1 -1
  252. package/package.json +9 -7
  253. package/dist/hooks/useCancelRequest.js +0 -31
  254. package/dist/hooks/useCancelRequest.js.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/binary-feedback/BinaryFeedbackView.tsx"],
4
- "sourcesContent": ["import { Option, SelectProps } from '@inkjs/ui'\nimport chalk from 'chalk'\nimport { Box, Text, useInput } from 'ink'\nimport Link from 'ink-link'\nimport React, { useState } from 'react'\nimport { getTheme } from '@utils/theme'\nimport { Select } from '@components/CustomSelect/select'\nimport type { Tool } from '@tool'\nimport type { NormalizedMessage } from '@utils/messages'\nimport { BinaryFeedbackOption } from './BinaryFeedbackOption'\nimport type { AssistantMessage } from '@query'\nimport type { BinaryFeedbackChoose } from './utils'\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\nimport { BinaryFeedbackChoice } from './utils'\nimport { PRODUCT_NAME } from '@constants/product'\n\nconst HELP_URL = 'https://go/cli-feedback'\n\ntype BinaryFeedbackOption = Option & { value: BinaryFeedbackChoice }\n\n// Make options a function to avoid early theme access during module initialization\nexport function getOptions(): BinaryFeedbackOption[] {\n return [\n {\n // This option combines the follow user intents:\n // - The two options look about equally good to me\n // - I don't feel confident enough to choose\n // - I don't want to choose right now\n label: 'Choose for me',\n value: 'no-preference',\n },\n {\n label: 'Left option looks better',\n value: 'prefer-left',\n },\n {\n label: 'Right option looks better',\n value: 'prefer-right',\n },\n {\n label: `Neither, and tell ${PRODUCT_NAME} what to do differently (${chalk.bold.hex(getTheme().warning)('esc')})`,\n value: 'neither',\n },\n ]\n}\n\ntype Props = {\n m1: AssistantMessage\n m2: AssistantMessage\n onChoose?: BinaryFeedbackChoose\n debug: boolean\n erroredToolUseIDs: Set<string>\n inProgressToolUseIDs: Set<string>\n normalizedMessages: NormalizedMessage[]\n tools: Tool[]\n unresolvedToolUseIDs: Set<string>\n verbose: boolean\n}\n\nexport function BinaryFeedbackView({\n m1,\n m2,\n onChoose,\n debug,\n erroredToolUseIDs,\n inProgressToolUseIDs,\n normalizedMessages,\n tools,\n unresolvedToolUseIDs,\n verbose,\n}: Props) {\n const theme = getTheme()\n const [focused, setFocus] = useState('no-preference')\n const [focusValue, setFocusValue] = useState<string | undefined>(undefined)\n const exitState = useExitOnCtrlCD(() => process.exit(1))\n\n useInput((_input, key) => {\n if (key.leftArrow) {\n setFocusValue('prefer-left')\n } else if (key.rightArrow) {\n setFocusValue('prefer-right')\n } else if (key.escape) {\n onChoose?.('neither')\n }\n })\n\n return (\n <>\n <Box\n flexDirection=\"column\"\n height=\"100%\"\n width=\"100%\"\n borderStyle=\"round\"\n borderColor={theme.permission}\n >\n <Box width=\"100%\" justifyContent=\"space-between\" paddingX={1}>\n <Text bold color={theme.permission}>\n [ANT-ONLY] Help train {PRODUCT_NAME}\n </Text>\n <Text>\n <Link url={HELP_URL}>[?]</Link>\n </Text>\n </Box>\n <Box flexDirection=\"row\" width=\"100%\" flexGrow={1} paddingTop={1}>\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n flexBasis={1}\n gap={1}\n borderStyle={focused === 'prefer-left' ? 'bold' : 'single'}\n borderColor={\n focused === 'prefer-left' ? theme.success : theme.secondaryBorder\n }\n marginRight={1}\n padding={1}\n >\n <BinaryFeedbackOption\n erroredToolUseIDs={erroredToolUseIDs}\n debug={debug}\n inProgressToolUseIDs={inProgressToolUseIDs}\n message={m1}\n normalizedMessages={normalizedMessages}\n tools={tools}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n verbose={verbose}\n />\n </Box>\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n flexBasis={1}\n gap={1}\n borderStyle={focused === 'prefer-right' ? 'bold' : 'single'}\n borderColor={\n focused === 'prefer-right' ? theme.success : theme.secondaryBorder\n }\n marginLeft={1}\n padding={1}\n >\n <BinaryFeedbackOption\n erroredToolUseIDs={erroredToolUseIDs}\n debug={debug}\n inProgressToolUseIDs={inProgressToolUseIDs}\n message={m2}\n normalizedMessages={normalizedMessages}\n tools={tools}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n verbose={verbose}\n />\n </Box>\n </Box>\n <Box flexDirection=\"column\" paddingTop={1} paddingX={1}>\n <Text>How do you want to proceed?</Text>\n <Select\n options={getOptions()}\n onFocus={setFocus}\n focusValue={focusValue}\n onChange={onChoose as SelectProps['onChange']}\n />\n </Box>\n </Box>\n {exitState.pending ? (\n <Box marginLeft={3}>\n <Text dimColor>Press {exitState.keyName} again to exit</Text>\n </Box>\n ) : (\n // Render a blank line so that the UI doesn't reflow when the exit message is shown\n <Text> </Text>\n )}\n </>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Option, SelectProps } from '@inkjs/ui'\nimport chalk from 'chalk'\nimport { Box, Text, useInput } from 'ink'\nimport Link from 'ink-link'\nimport React, { useState } from 'react'\nimport { getTheme } from '@utils/theme'\nimport { Select } from '@components/CustomSelect/select'\nimport type { Tool } from '@tool'\nimport type { NormalizedMessage } from '@utils/messages'\nimport { BinaryFeedbackOption } from './BinaryFeedbackOption'\nimport type { AssistantMessage } from '@query'\nimport type { BinaryFeedbackChoose } from './utils'\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\nimport { BinaryFeedbackChoice } from './utils'\nimport { PRODUCT_NAME } from '@constants/product'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\nconst HELP_URL = 'https://go/cli-feedback'\n\ntype BinaryFeedbackOption = Option & { value: BinaryFeedbackChoice }\n\n// Make options a function to avoid early theme access during module initialization\nexport function getOptions(): BinaryFeedbackOption[] {\n return [\n {\n // This option combines the follow user intents:\n // - The two options look about equally good to me\n // - I don't feel confident enough to choose\n // - I don't want to choose right now\n label: 'Choose for me',\n value: 'no-preference',\n },\n {\n label: 'Left option looks better',\n value: 'prefer-left',\n },\n {\n label: 'Right option looks better',\n value: 'prefer-right',\n },\n {\n label: `Neither, and tell ${PRODUCT_NAME} what to do differently (${chalk.bold.hex(getTheme().warning)('esc')})`,\n value: 'neither',\n },\n ]\n}\n\ntype Props = {\n m1: AssistantMessage\n m2: AssistantMessage\n onChoose?: BinaryFeedbackChoose\n debug: boolean\n erroredToolUseIDs: Set<string>\n inProgressToolUseIDs: Set<string>\n normalizedMessages: NormalizedMessage[]\n tools: Tool[]\n unresolvedToolUseIDs: Set<string>\n verbose: boolean\n}\n\nexport function BinaryFeedbackView({\n m1,\n m2,\n onChoose,\n debug,\n erroredToolUseIDs,\n inProgressToolUseIDs,\n normalizedMessages,\n tools,\n unresolvedToolUseIDs,\n verbose,\n}: Props) {\n const theme = getTheme()\n const [focused, setFocus] = useState('no-preference')\n const [focusValue, setFocusValue] = useState<string | undefined>(undefined)\n const exitState = useExitOnCtrlCD(() => process.exit(1))\n\n useInput((_input, key) => {\n if (key.leftArrow) {\n setFocusValue('prefer-left')\n } else if (key.rightArrow) {\n setFocusValue('prefer-right')\n } else if (key.escape) {\n onChoose?.('neither')\n }\n })\n\n return (\n <>\n <Box\n flexDirection=\"column\"\n height=\"100%\"\n width=\"100%\"\n borderStyle=\"round\"\n borderColor={theme.permission}\n >\n <Box width=\"100%\" justifyContent=\"space-between\" paddingX={1}>\n <Text bold color={theme.permission}>\n [ANT-ONLY] Help train {PRODUCT_NAME}\n </Text>\n <Text>\n <Link url={HELP_URL}>[?]</Link>\n </Text>\n </Box>\n <Box flexDirection=\"row\" width=\"100%\" flexGrow={1} paddingTop={1}>\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n flexBasis={1}\n gap={1}\n borderStyle={focused === 'prefer-left' ? 'bold' : 'single'}\n borderColor={\n focused === 'prefer-left' ? theme.success : theme.secondaryBorder\n }\n marginRight={1}\n padding={1}\n >\n <BinaryFeedbackOption\n erroredToolUseIDs={erroredToolUseIDs}\n debug={debug}\n inProgressToolUseIDs={inProgressToolUseIDs}\n message={m1}\n normalizedMessages={normalizedMessages}\n tools={tools}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n verbose={verbose}\n />\n </Box>\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n flexBasis={1}\n gap={1}\n borderStyle={focused === 'prefer-right' ? 'bold' : 'single'}\n borderColor={\n focused === 'prefer-right' ? theme.success : theme.secondaryBorder\n }\n marginLeft={1}\n padding={1}\n >\n <BinaryFeedbackOption\n erroredToolUseIDs={erroredToolUseIDs}\n debug={debug}\n inProgressToolUseIDs={inProgressToolUseIDs}\n message={m2}\n normalizedMessages={normalizedMessages}\n tools={tools}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n verbose={verbose}\n />\n </Box>\n </Box>\n <Box flexDirection=\"column\" paddingTop={1} paddingX={1}>\n <Text>How do you want to proceed?</Text>\n <Select\n options={getOptions()}\n onFocus={setFocus}\n focusValue={focusValue}\n onChange={onChoose as SelectProps['onChange']}\n />\n </Box>\n </Box>\n {exitState.pending ? (\n <Box marginLeft={3}>\n <Text color={SEMANTIC_COLORS.dim}>\n Press {exitState.keyName} again to exit\n </Text>\n </Box>\n ) : (\n // Render a blank line so that the UI doesn't reflow when the exit message is shown\n <Text> </Text>\n )}\n </>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import { AssistantBashOutputMessage } from "./AssistantBashOutputMessage.js";
3
3
  import { AssistantLocalCommandOutputMessage } from "./AssistantLocalCommandOutputMessage.js";
4
- import { getTheme } from "../../utils/theme.js";
5
4
  import { Box, Text } from "ink";
6
5
  import { Cost } from "../Cost.js";
7
6
  import {
@@ -20,7 +19,12 @@ import {
20
19
  import { BLACK_CIRCLE } from "../../constants/figures.js";
21
20
  import { applyMarkdown } from "../../utils/markdown.js";
22
21
  import { useTerminalSize } from "../../hooks/useTerminalSize.js";
23
- import { formatTimestamp } from "../../utils/format.js";
22
+ import { formatMetaInfo } from "../../utils/taskDisplayUtils.js";
23
+ import {
24
+ SEMANTIC_COLORS,
25
+ SYMBOL_COLORS,
26
+ VALUE_TIER_COLORS
27
+ } from "../../constants/colors.js";
24
28
  function AssistantTextMessage({
25
29
  param: { text },
26
30
  costUSD,
@@ -43,7 +47,7 @@ function AssistantTextMessage({
43
47
  return /* @__PURE__ */ React.createElement(AssistantLocalCommandOutputMessage, { content: text });
44
48
  }
45
49
  if (text.startsWith(API_ERROR_MESSAGE_PREFIX)) {
46
- return /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0", /* @__PURE__ */ React.createElement(Text, { color: getTheme().error }, text === API_ERROR_MESSAGE_PREFIX ? `${API_ERROR_MESSAGE_PREFIX}: Please wait a moment and try again.` : text));
50
+ return /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, text === API_ERROR_MESSAGE_PREFIX ? `${API_ERROR_MESSAGE_PREFIX}: Please try again` : text));
47
51
  }
48
52
  switch (text) {
49
53
  // Local JSX commands don't need a response, but we still want the assistant to see them
@@ -53,13 +57,13 @@ function AssistantTextMessage({
53
57
  return null;
54
58
  case INTERRUPT_MESSAGE:
55
59
  case CANCEL_MESSAGE:
56
- return /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0", /* @__PURE__ */ React.createElement(Text, { color: getTheme().error }, "Interrupted by user"));
60
+ return /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, "Cancelled"));
57
61
  case PROMPT_TOO_LONG_ERROR_MESSAGE:
58
- return /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0", /* @__PURE__ */ React.createElement(Text, { color: getTheme().error }, "Context low \xB7 Run /compact to compact & continue"));
62
+ return /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, "Context too long \xB7 Run /compact to continue"));
59
63
  case CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE:
60
- return /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0", /* @__PURE__ */ React.createElement(Text, { color: getTheme().error }, "Credit balance too low \xB7 Add funds: https://console.anthropic.com/settings/billing"));
64
+ return /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, "Insufficient credits \xB7 Top up: https://console.anthropic.com/settings/billing"));
61
65
  case INVALID_API_KEY_ERROR_MESSAGE:
62
- return /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0", /* @__PURE__ */ React.createElement(Text, { color: getTheme().error }, INVALID_API_KEY_ERROR_MESSAGE));
66
+ return /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, "Invalid API key"));
63
67
  default:
64
68
  return /* @__PURE__ */ React.createElement(
65
69
  Box,
@@ -70,8 +74,12 @@ function AssistantTextMessage({
70
74
  marginTop: addMargin ? 1 : 0,
71
75
  width: "100%"
72
76
  },
73
- /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, shouldShowDot && /* @__PURE__ */ React.createElement(Box, { minWidth: 2 }, /* @__PURE__ */ React.createElement(Text, { color: getTheme().text }, BLACK_CIRCLE)), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: columns - 6 }, /* @__PURE__ */ React.createElement(Text, null, applyMarkdown(text)))),
74
- /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", alignItems: "flex-end" }, /* @__PURE__ */ React.createElement(Cost, { costUSD, durationMs, debug }), verbose && (timestamp || modelId) && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, timestamp ? formatTimestamp(timestamp) : "", timestamp && modelId ? " " : "", modelId || ""))
77
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, shouldShowDot && /* @__PURE__ */ React.createElement(Box, { minWidth: 2 }, /* @__PURE__ */ React.createElement(Text, { color: SYMBOL_COLORS.success }, BLACK_CIRCLE)), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: columns - 6 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.primary }, applyMarkdown(text)))),
78
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", alignItems: "flex-end" }, /* @__PURE__ */ React.createElement(Cost, { costUSD, durationMs, debug }), verbose && (timestamp || modelId || durationMs > 0) && /* @__PURE__ */ React.createElement(Text, { color: VALUE_TIER_COLORS.meta }, formatMetaInfo({
79
+ duration: durationMs > 0 ? durationMs : void 0,
80
+ model: modelId,
81
+ timestamp
82
+ })))
75
83
  );
76
84
  }
77
85
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/messages/AssistantTextMessage.tsx"],
4
- "sourcesContent": ["import { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport React from 'react'\nimport { AssistantBashOutputMessage } from './AssistantBashOutputMessage'\nimport { AssistantLocalCommandOutputMessage } from './AssistantLocalCommandOutputMessage'\nimport { getTheme } from '@utils/theme'\nimport { Box, Text } from 'ink'\nimport { Cost } from '@components/Cost'\nimport {\n API_ERROR_MESSAGE_PREFIX,\n CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE,\n INVALID_API_KEY_ERROR_MESSAGE,\n PROMPT_TOO_LONG_ERROR_MESSAGE,\n} from '@services/claude'\nimport {\n CANCEL_MESSAGE,\n INTERRUPT_MESSAGE,\n INTERRUPT_MESSAGE_FOR_TOOL_USE,\n isEmptyMessageText,\n NO_RESPONSE_REQUESTED,\n} from '@utils/messages'\nimport { BLACK_CIRCLE } from '@constants/figures'\nimport { applyMarkdown } from '@utils/markdown'\nimport { useTerminalSize } from '@hooks/useTerminalSize'\nimport { formatTimestamp } from '@utils/format'\n\ntype Props = {\n param: TextBlockParam\n costUSD: number\n durationMs: number\n debug: boolean\n addMargin: boolean\n shouldShowDot: boolean\n verbose?: boolean\n width?: number | string\n /** Timestamp for verbose mode display */\n timestamp?: number\n /** Model ID for verbose mode display */\n modelId?: string\n}\n\nexport function AssistantTextMessage({\n param: { text },\n costUSD,\n durationMs,\n debug,\n addMargin,\n shouldShowDot,\n verbose,\n timestamp,\n modelId,\n}: Props): React.ReactNode {\n const { columns } = useTerminalSize()\n if (isEmptyMessageText(text)) {\n return null\n }\n\n // Show bash output\n if (text.startsWith('<bash-stdout') || text.startsWith('<bash-stderr')) {\n return <AssistantBashOutputMessage content={text} verbose={verbose} />\n }\n\n // Show command output\n if (\n text.startsWith('<local-command-stdout') ||\n text.startsWith('<local-command-stderr')\n ) {\n return <AssistantLocalCommandOutputMessage content={text} />\n }\n\n if (text.startsWith(API_ERROR_MESSAGE_PREFIX)) {\n return (\n <Text>\n &nbsp;&nbsp;\u23BF &nbsp;\n <Text color={getTheme().error}>\n {text === API_ERROR_MESSAGE_PREFIX\n ? `${API_ERROR_MESSAGE_PREFIX}: Please wait a moment and try again.`\n : text}\n </Text>\n </Text>\n )\n }\n\n switch (text) {\n // Local JSX commands don't need a response, but we still want the assistant to see them\n // Tool results render their own interrupt messages\n case NO_RESPONSE_REQUESTED:\n case INTERRUPT_MESSAGE_FOR_TOOL_USE:\n return null\n\n case INTERRUPT_MESSAGE:\n case CANCEL_MESSAGE:\n return (\n <Text>\n &nbsp;&nbsp;\u23BF &nbsp;\n <Text color={getTheme().error}>Interrupted by user</Text>\n </Text>\n )\n\n case PROMPT_TOO_LONG_ERROR_MESSAGE:\n return (\n <Text>\n &nbsp;&nbsp;\u23BF &nbsp;\n <Text color={getTheme().error}>\n Context low &middot; Run /compact to compact & continue\n </Text>\n </Text>\n )\n\n case CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE:\n return (\n <Text>\n &nbsp;&nbsp;\u23BF &nbsp;\n <Text color={getTheme().error}>\n Credit balance too low &middot; Add funds:\n https://console.anthropic.com/settings/billing\n </Text>\n </Text>\n )\n\n case INVALID_API_KEY_ERROR_MESSAGE:\n return (\n <Text>\n &nbsp;&nbsp;\u23BF &nbsp;\n <Text color={getTheme().error}>{INVALID_API_KEY_ERROR_MESSAGE}</Text>\n </Text>\n )\n\n default:\n return (\n <Box\n alignItems=\"flex-start\"\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n marginTop={addMargin ? 1 : 0}\n width=\"100%\"\n >\n <Box flexDirection=\"row\">\n {shouldShowDot && (\n <Box minWidth={2}>\n <Text color={getTheme().text}>{BLACK_CIRCLE}</Text>\n </Box>\n )}\n <Box flexDirection=\"column\" width={columns - 6}>\n <Text>{applyMarkdown(text)}</Text>\n </Box>\n </Box>\n <Box flexDirection=\"column\" alignItems=\"flex-end\">\n <Cost costUSD={costUSD} durationMs={durationMs} debug={debug} />\n {/* Verbose mode: show timestamp and model ID */}\n {verbose && (timestamp || modelId) && (\n <Text dimColor>\n {timestamp ? formatTimestamp(timestamp) : ''}\n {timestamp && modelId ? ' ' : ''}\n {modelId || ''}\n </Text>\n )}\n </Box>\n </Box>\n )\n }\n}\n"],
5
- "mappings": "AACA,OAAO,WAAW;AAClB,SAAS,kCAAkC;AAC3C,SAAS,0CAA0C;AACnD,SAAS,gBAAgB;AACzB,SAAS,KAAK,YAAY;AAC1B,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAiBzB,SAAS,qBAAqB;AAAA,EACnC,OAAO,EAAE,KAAK;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,EAAE,QAAQ,IAAI,gBAAgB;AACpC,MAAI,mBAAmB,IAAI,GAAG;AAC5B,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,WAAW,cAAc,KAAK,KAAK,WAAW,cAAc,GAAG;AACtE,WAAO,oCAAC,8BAA2B,SAAS,MAAM,SAAkB;AAAA,EACtE;AAGA,MACE,KAAK,WAAW,uBAAuB,KACvC,KAAK,WAAW,uBAAuB,GACvC;AACA,WAAO,oCAAC,sCAAmC,SAAS,MAAM;AAAA,EAC5D;AAEA,MAAI,KAAK,WAAW,wBAAwB,GAAG;AAC7C,WACE,oCAAC,YAAK,uBAEJ,oCAAC,QAAK,OAAO,SAAS,EAAE,SACrB,SAAS,2BACN,GAAG,wBAAwB,0CAC3B,IACN,CACF;AAAA,EAEJ;AAEA,UAAQ,MAAM;AAAA;AAAA;AAAA,IAGZ,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IAET,KAAK;AAAA,IACL,KAAK;AACH,aACE,oCAAC,YAAK,uBAEJ,oCAAC,QAAK,OAAO,SAAS,EAAE,SAAO,qBAAmB,CACpD;AAAA,IAGJ,KAAK;AACH,aACE,oCAAC,YAAK,uBAEJ,oCAAC,QAAK,OAAO,SAAS,EAAE,SAAO,qDAE/B,CACF;AAAA,IAGJ,KAAK;AACH,aACE,oCAAC,YAAK,uBAEJ,oCAAC,QAAK,OAAO,SAAS,EAAE,SAAO,uFAG/B,CACF;AAAA,IAGJ,KAAK;AACH,aACE,oCAAC,YAAK,uBAEJ,oCAAC,QAAK,OAAO,SAAS,EAAE,SAAQ,6BAA8B,CAChE;AAAA,IAGJ;AACE,aACE;AAAA,QAAC;AAAA;AAAA,UACC,YAAW;AAAA,UACX,eAAc;AAAA,UACd,gBAAe;AAAA,UACf,WAAW,YAAY,IAAI;AAAA,UAC3B,OAAM;AAAA;AAAA,QAEN,oCAAC,OAAI,eAAc,SAChB,iBACC,oCAAC,OAAI,UAAU,KACb,oCAAC,QAAK,OAAO,SAAS,EAAE,QAAO,YAAa,CAC9C,GAEF,oCAAC,OAAI,eAAc,UAAS,OAAO,UAAU,KAC3C,oCAAC,YAAM,cAAc,IAAI,CAAE,CAC7B,CACF;AAAA,QACA,oCAAC,OAAI,eAAc,UAAS,YAAW,cACrC,oCAAC,QAAK,SAAkB,YAAwB,OAAc,GAE7D,YAAY,aAAa,YACxB,oCAAC,QAAK,UAAQ,QACX,YAAY,gBAAgB,SAAS,IAAI,IACzC,aAAa,UAAU,OAAO,IAC9B,WAAW,EACd,CAEJ;AAAA,MACF;AAAA,EAEN;AACF;",
4
+ "sourcesContent": ["import { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport React from 'react'\nimport { AssistantBashOutputMessage } from './AssistantBashOutputMessage'\nimport { AssistantLocalCommandOutputMessage } from './AssistantLocalCommandOutputMessage'\nimport { getTheme } from '@utils/theme'\nimport { Box, Text } from 'ink'\nimport { Cost } from '@components/Cost'\nimport {\n API_ERROR_MESSAGE_PREFIX,\n CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE,\n INVALID_API_KEY_ERROR_MESSAGE,\n PROMPT_TOO_LONG_ERROR_MESSAGE,\n} from '@services/claude'\nimport {\n CANCEL_MESSAGE,\n INTERRUPT_MESSAGE,\n INTERRUPT_MESSAGE_FOR_TOOL_USE,\n isEmptyMessageText,\n NO_RESPONSE_REQUESTED,\n} from '@utils/messages'\nimport { BLACK_CIRCLE } from '@constants/figures'\nimport { applyMarkdown } from '@utils/markdown'\nimport { useTerminalSize } from '@hooks/useTerminalSize'\nimport { formatMetaInfo } from '@utils/taskDisplayUtils'\nimport {\n SEMANTIC_COLORS,\n SYMBOL_COLORS,\n VALUE_TIER_COLORS,\n} from '@constants/colors'\n\ntype Props = {\n param: TextBlockParam\n costUSD: number\n durationMs: number\n debug: boolean\n addMargin: boolean\n shouldShowDot: boolean\n verbose?: boolean\n width?: number | string\n /** Timestamp for verbose mode display */\n timestamp?: number\n /** Model ID for verbose mode display */\n modelId?: string\n}\n\nexport function AssistantTextMessage({\n param: { text },\n costUSD,\n durationMs,\n debug,\n addMargin,\n shouldShowDot,\n verbose,\n timestamp,\n modelId,\n}: Props): React.ReactNode {\n const { columns } = useTerminalSize()\n if (isEmptyMessageText(text)) {\n return null\n }\n\n // Show bash output\n if (text.startsWith('<bash-stdout') || text.startsWith('<bash-stderr')) {\n return <AssistantBashOutputMessage content={text} verbose={verbose} />\n }\n\n // Show command output\n if (\n text.startsWith('<local-command-stdout') ||\n text.startsWith('<local-command-stderr')\n ) {\n return <AssistantLocalCommandOutputMessage content={text} />\n }\n\n if (text.startsWith(API_ERROR_MESSAGE_PREFIX)) {\n return (\n <Text>\n &nbsp;&nbsp;\u23BF &nbsp;\n <Text color={SEMANTIC_COLORS.error}>\n {text === API_ERROR_MESSAGE_PREFIX\n ? `${API_ERROR_MESSAGE_PREFIX}: Please try again`\n : text}\n </Text>\n </Text>\n )\n }\n\n switch (text) {\n // Local JSX commands don't need a response, but we still want the assistant to see them\n // Tool results render their own interrupt messages\n case NO_RESPONSE_REQUESTED:\n case INTERRUPT_MESSAGE_FOR_TOOL_USE:\n return null\n\n case INTERRUPT_MESSAGE:\n case CANCEL_MESSAGE:\n return (\n <Text>\n &nbsp;&nbsp;\u23BF &nbsp;\n <Text color={SEMANTIC_COLORS.error}>Cancelled</Text>\n </Text>\n )\n\n case PROMPT_TOO_LONG_ERROR_MESSAGE:\n return (\n <Text>\n &nbsp;&nbsp;\u23BF &nbsp;\n <Text color={SEMANTIC_COLORS.error}>\n Context too long \u00B7 Run /compact to continue\n </Text>\n </Text>\n )\n\n case CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE:\n return (\n <Text>\n &nbsp;&nbsp;\u23BF &nbsp;\n <Text color={SEMANTIC_COLORS.error}>\n Insufficient credits \u00B7 Top up:\n https://console.anthropic.com/settings/billing\n </Text>\n </Text>\n )\n\n case INVALID_API_KEY_ERROR_MESSAGE:\n return (\n <Text>\n &nbsp;&nbsp;\u23BF &nbsp;\n <Text color={SEMANTIC_COLORS.error}>Invalid API key</Text>\n </Text>\n )\n\n default:\n return (\n <Box\n alignItems=\"flex-start\"\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n marginTop={addMargin ? 1 : 0}\n width=\"100%\"\n >\n <Box flexDirection=\"row\">\n {shouldShowDot && (\n <Box minWidth={2}>\n <Text color={SYMBOL_COLORS.success}>{BLACK_CIRCLE}</Text>\n </Box>\n )}\n <Box flexDirection=\"column\" width={columns - 6}>\n <Text color={SEMANTIC_COLORS.primary}>{applyMarkdown(text)}</Text>\n </Box>\n </Box>\n <Box flexDirection=\"column\" alignItems=\"flex-end\">\n <Cost costUSD={costUSD} durationMs={durationMs} debug={debug} />\n {/* Verbose mode: duration \u00B7 model \u00B7 time */}\n {verbose && (timestamp || modelId || durationMs > 0) && (\n <Text color={VALUE_TIER_COLORS.meta}>\n {formatMetaInfo({\n duration: durationMs > 0 ? durationMs : undefined,\n model: modelId,\n timestamp: timestamp,\n })}\n </Text>\n )}\n </Box>\n </Box>\n )\n }\n}\n"],
5
+ "mappings": "AACA,OAAO,WAAW;AAClB,SAAS,kCAAkC;AAC3C,SAAS,0CAA0C;AAEnD,SAAS,KAAK,YAAY;AAC1B,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAiBA,SAAS,qBAAqB;AAAA,EACnC,OAAO,EAAE,KAAK;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,EAAE,QAAQ,IAAI,gBAAgB;AACpC,MAAI,mBAAmB,IAAI,GAAG;AAC5B,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,WAAW,cAAc,KAAK,KAAK,WAAW,cAAc,GAAG;AACtE,WAAO,oCAAC,8BAA2B,SAAS,MAAM,SAAkB;AAAA,EACtE;AAGA,MACE,KAAK,WAAW,uBAAuB,KACvC,KAAK,WAAW,uBAAuB,GACvC;AACA,WAAO,oCAAC,sCAAmC,SAAS,MAAM;AAAA,EAC5D;AAEA,MAAI,KAAK,WAAW,wBAAwB,GAAG;AAC7C,WACE,oCAAC,YAAK,uBAEJ,oCAAC,QAAK,OAAO,gBAAgB,SAC1B,SAAS,2BACN,GAAG,wBAAwB,uBAC3B,IACN,CACF;AAAA,EAEJ;AAEA,UAAQ,MAAM;AAAA;AAAA;AAAA,IAGZ,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IAET,KAAK;AAAA,IACL,KAAK;AACH,aACE,oCAAC,YAAK,uBAEJ,oCAAC,QAAK,OAAO,gBAAgB,SAAO,WAAS,CAC/C;AAAA,IAGJ,KAAK;AACH,aACE,oCAAC,YAAK,uBAEJ,oCAAC,QAAK,OAAO,gBAAgB,SAAO,gDAEpC,CACF;AAAA,IAGJ,KAAK;AACH,aACE,oCAAC,YAAK,uBAEJ,oCAAC,QAAK,OAAO,gBAAgB,SAAO,kFAGpC,CACF;AAAA,IAGJ,KAAK;AACH,aACE,oCAAC,YAAK,uBAEJ,oCAAC,QAAK,OAAO,gBAAgB,SAAO,iBAAe,CACrD;AAAA,IAGJ;AACE,aACE;AAAA,QAAC;AAAA;AAAA,UACC,YAAW;AAAA,UACX,eAAc;AAAA,UACd,gBAAe;AAAA,UACf,WAAW,YAAY,IAAI;AAAA,UAC3B,OAAM;AAAA;AAAA,QAEN,oCAAC,OAAI,eAAc,SAChB,iBACC,oCAAC,OAAI,UAAU,KACb,oCAAC,QAAK,OAAO,cAAc,WAAU,YAAa,CACpD,GAEF,oCAAC,OAAI,eAAc,UAAS,OAAO,UAAU,KAC3C,oCAAC,QAAK,OAAO,gBAAgB,WAAU,cAAc,IAAI,CAAE,CAC7D,CACF;AAAA,QACA,oCAAC,OAAI,eAAc,UAAS,YAAW,cACrC,oCAAC,QAAK,SAAkB,YAAwB,OAAc,GAE7D,YAAY,aAAa,WAAW,aAAa,MAChD,oCAAC,QAAK,OAAO,kBAAkB,QAC5B,eAAe;AAAA,UACd,UAAU,aAAa,IAAI,aAAa;AAAA,UACxC,OAAO;AAAA,UACP;AAAA,QACF,CAAC,CACH,CAEJ;AAAA,MACF;AAAA,EAEN;AACF;",
6
6
  "names": []
7
7
  }
@@ -3,13 +3,13 @@ import React from "react";
3
3
  import { logError } from "../../utils/log.js";
4
4
  import { Cost } from "../Cost.js";
5
5
  import { ToolUseLoader } from "../ToolUseLoader.js";
6
- import { getTheme } from "../../utils/theme.js";
7
6
  import { BLACK_CIRCLE } from "../../constants/figures.js";
8
7
  import { ThinkTool } from "../../tools/ThinkTool/ThinkTool.js";
9
8
  import { AssistantThinkingMessage } from "./AssistantThinkingMessage.js";
10
9
  import { TaskToolMessage } from "./TaskToolMessage.js";
11
10
  import { safeRenderToolUseMessage } from "../../utils/tooling/safeRender.js";
12
- import { formatTimestamp } from "../../utils/format.js";
11
+ import { formatMetaInfo } from "../../utils/taskDisplayUtils.js";
12
+ import { SEMANTIC_COLORS, VALUE_TIER_COLORS } from "../../constants/colors.js";
13
13
  function AssistantToolUseMessage({
14
14
  param,
15
15
  costUSD,
@@ -31,7 +31,7 @@ function AssistantToolUseMessage({
31
31
  return null;
32
32
  }
33
33
  const isQueued = !inProgressToolUseIDs.has(param.id) && unresolvedToolUseIDs.has(param.id);
34
- const color = isQueued ? getTheme().secondaryText : void 0;
34
+ const color = isQueued ? SEMANTIC_COLORS.dim : void 0;
35
35
  if (tool === ThinkTool) {
36
36
  const { thought } = ThinkTool.inputSchema.parse(param.input);
37
37
  return /* @__PURE__ */ React.createElement(
@@ -87,7 +87,11 @@ function AssistantToolUseMessage({
87
87
  }
88
88
  return /* @__PURE__ */ React.createElement(Text, { color }, "(", toolMessage, ")");
89
89
  })(), /* @__PURE__ */ React.createElement(Text, { color }, "\u2026"))),
90
- /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", alignItems: "flex-end" }, /* @__PURE__ */ React.createElement(Cost, { costUSD, durationMs, debug }), verbose && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, formatTimestamp(Date.now()), modelId ? ` ${modelId}` : "", durationMs > 0 ? ` ${(durationMs / 1e3).toFixed(1)}s` : ""))
90
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", alignItems: "flex-end" }, /* @__PURE__ */ React.createElement(Cost, { costUSD, durationMs, debug }), verbose && /* @__PURE__ */ React.createElement(Text, { color: VALUE_TIER_COLORS.meta }, formatMetaInfo({
91
+ duration: durationMs > 0 ? durationMs : void 0,
92
+ model: modelId,
93
+ timestamp: Date.now()
94
+ })))
91
95
  );
92
96
  }
93
97
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/messages/AssistantToolUseMessage.tsx"],
4
- "sourcesContent": ["import { Box, Text } from 'ink'\nimport React from 'react'\nimport { logError } from '@utils/log'\nimport { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { Tool } from '@tool'\nimport { Cost } from '@components/Cost'\nimport { ToolUseLoader } from '@components/ToolUseLoader'\nimport { getTheme } from '@utils/theme'\nimport { BLACK_CIRCLE } from '@constants/figures'\nimport { ThinkTool } from '@tools/ThinkTool/ThinkTool'\nimport { AssistantThinkingMessage } from './AssistantThinkingMessage'\nimport { TaskToolMessage } from './TaskToolMessage'\nimport { safeRenderToolUseMessage } from '@utils/tooling/safeRender'\nimport { formatTimestamp } from '@utils/format'\n\ntype Props = {\n param: ToolUseBlockParam\n costUSD: number\n durationMs: number\n addMargin: boolean\n tools: Tool[]\n debug: boolean\n verbose: boolean\n erroredToolUseIDs: Set<string>\n inProgressToolUseIDs: Set<string>\n unresolvedToolUseIDs: Set<string>\n shouldAnimate: boolean\n shouldShowDot: boolean\n /** Model ID for verbose mode display */\n modelId?: string\n}\n\nexport function AssistantToolUseMessage({\n param,\n costUSD,\n durationMs,\n addMargin,\n tools,\n debug,\n verbose,\n erroredToolUseIDs,\n inProgressToolUseIDs,\n unresolvedToolUseIDs,\n shouldAnimate,\n shouldShowDot,\n modelId,\n}: Props): React.ReactNode {\n const tool = tools.find(_ => _.name === param.name)\n if (!tool) {\n logError(`Tool ${param.name} not found`)\n return null\n }\n const isQueued =\n !inProgressToolUseIDs.has(param.id) && unresolvedToolUseIDs.has(param.id)\n // Keeping color undefined makes the OS use the default color regardless of appearance\n const color = isQueued ? getTheme().secondaryText : undefined\n\n // Handle thinking tool with specialized rendering\n if (tool === ThinkTool) {\n const { thought } = ThinkTool.inputSchema.parse(param.input)\n return (\n <AssistantThinkingMessage\n param={{ thinking: thought, signature: '', type: 'thinking' }}\n addMargin={addMargin}\n />\n )\n }\n\n const userFacingToolName = tool.userFacingName\n ? tool.userFacingName()\n : tool.name\n return (\n <Box\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n marginTop={addMargin ? 1 : 0}\n width=\"100%\"\n >\n <Box>\n <Box\n flexWrap=\"nowrap\"\n minWidth={userFacingToolName.length + (shouldShowDot ? 2 : 0)}\n >\n {shouldShowDot &&\n (isQueued ? (\n <Box minWidth={2}>\n <Text color={color}>{BLACK_CIRCLE}</Text>\n </Box>\n ) : (\n <ToolUseLoader\n shouldAnimate={shouldAnimate}\n isUnresolved={unresolvedToolUseIDs.has(param.id)}\n isError={erroredToolUseIDs.has(param.id)}\n />\n ))}\n {tool.name === 'Task' && param.input ? (\n <TaskToolMessage\n agentType={String(\n (param.input as any).subagent_type || 'general-purpose',\n )}\n bold={Boolean(!isQueued)}\n children={String(userFacingToolName || '')}\n />\n ) : (\n <Text color={color} bold={!isQueued}>\n {userFacingToolName}\n </Text>\n )}\n </Box>\n <Box flexWrap=\"nowrap\">\n {Object.keys(param.input as { [key: string]: unknown }).length > 0 &&\n (() => {\n const toolMessage = safeRenderToolUseMessage(tool, param.input, {\n verbose,\n })\n\n // TodoWriteTool: Special formatting - message already includes parentheses and formatting\n // Format: \" (1 running, 2 pending): taskName\" (note leading space, parens around stats only)\n if (tool.name === 'TodoWrite') {\n return <Text color={color}>{toolMessage}</Text>\n }\n\n // If the tool returns a React component, render it directly\n if (React.isValidElement(toolMessage)) {\n return (\n <Box flexDirection=\"row\">\n <Text color={color}>(</Text>\n {toolMessage}\n <Text color={color}>)</Text>\n </Box>\n )\n }\n\n // If it's a string, wrap it in Text\n return <Text color={color}>({toolMessage})</Text>\n })()}\n <Text color={color}>\u2026</Text>\n </Box>\n </Box>\n <Box flexDirection=\"column\" alignItems=\"flex-end\">\n <Cost costUSD={costUSD} durationMs={durationMs} debug={debug} />\n {/* Verbose mode: show timestamp, model, and tool ID */}\n {verbose && (\n <Text dimColor>\n {formatTimestamp(Date.now())}\n {modelId ? ` ${modelId}` : ''}\n {durationMs > 0 ? ` ${(durationMs / 1000).toFixed(1)}s` : ''}\n </Text>\n )}\n </Box>\n </Box>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box, Text } from 'ink'\nimport React from 'react'\nimport { logError } from '@utils/log'\nimport { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { Tool } from '@tool'\nimport { Cost } from '@components/Cost'\nimport { ToolUseLoader } from '@components/ToolUseLoader'\nimport { BLACK_CIRCLE } from '@constants/figures'\nimport { ThinkTool } from '@tools/ThinkTool/ThinkTool'\nimport { AssistantThinkingMessage } from './AssistantThinkingMessage'\nimport { TaskToolMessage } from './TaskToolMessage'\nimport { safeRenderToolUseMessage } from '@utils/tooling/safeRender'\nimport { formatMetaInfo } from '@utils/taskDisplayUtils'\nimport { SEMANTIC_COLORS, VALUE_TIER_COLORS } from '@constants/colors'\n\ntype Props = {\n param: ToolUseBlockParam\n costUSD: number\n durationMs: number\n addMargin: boolean\n tools: Tool[]\n debug: boolean\n verbose: boolean\n erroredToolUseIDs: Set<string>\n inProgressToolUseIDs: Set<string>\n unresolvedToolUseIDs: Set<string>\n shouldAnimate: boolean\n shouldShowDot: boolean\n /** Model ID for verbose mode display */\n modelId?: string\n}\n\nexport function AssistantToolUseMessage({\n param,\n costUSD,\n durationMs,\n addMargin,\n tools,\n debug,\n verbose,\n erroredToolUseIDs,\n inProgressToolUseIDs,\n unresolvedToolUseIDs,\n shouldAnimate,\n shouldShowDot,\n modelId,\n}: Props): React.ReactNode {\n const tool = tools.find(_ => _.name === param.name)\n if (!tool) {\n logError(`Tool ${param.name} not found`)\n return null\n }\n const isQueued =\n !inProgressToolUseIDs.has(param.id) && unresolvedToolUseIDs.has(param.id)\n // \u4F7F\u7528\u8BED\u4E49\u989C\u8272\uFF1A\u6392\u961F\u4E2D\u7528 dim\uFF0C\u8FDB\u884C\u4E2D\u7528\u9ED8\u8BA4\n const color = isQueued ? SEMANTIC_COLORS.dim : undefined\n\n // Handle thinking tool with specialized rendering\n if (tool === ThinkTool) {\n const { thought } = ThinkTool.inputSchema.parse(param.input)\n return (\n <AssistantThinkingMessage\n param={{ thinking: thought, signature: '', type: 'thinking' }}\n addMargin={addMargin}\n />\n )\n }\n\n const userFacingToolName = tool.userFacingName\n ? tool.userFacingName()\n : tool.name\n return (\n <Box\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n marginTop={addMargin ? 1 : 0}\n width=\"100%\"\n >\n <Box>\n <Box\n flexWrap=\"nowrap\"\n minWidth={userFacingToolName.length + (shouldShowDot ? 2 : 0)}\n >\n {shouldShowDot &&\n (isQueued ? (\n <Box minWidth={2}>\n <Text color={color}>{BLACK_CIRCLE}</Text>\n </Box>\n ) : (\n <ToolUseLoader\n shouldAnimate={shouldAnimate}\n isUnresolved={unresolvedToolUseIDs.has(param.id)}\n isError={erroredToolUseIDs.has(param.id)}\n />\n ))}\n {tool.name === 'Task' && param.input ? (\n <TaskToolMessage\n agentType={String(\n (param.input as any).subagent_type || 'general-purpose',\n )}\n bold={Boolean(!isQueued)}\n children={String(userFacingToolName || '')}\n />\n ) : (\n <Text color={color} bold={!isQueued}>\n {userFacingToolName}\n </Text>\n )}\n </Box>\n <Box flexWrap=\"nowrap\">\n {Object.keys(param.input as { [key: string]: unknown }).length > 0 &&\n (() => {\n const toolMessage = safeRenderToolUseMessage(tool, param.input, {\n verbose,\n })\n\n // TodoWriteTool: Special formatting - message already includes parentheses and formatting\n // Format: \" (1 running, 2 pending): taskName\" (note leading space, parens around stats only)\n if (tool.name === 'TodoWrite') {\n return <Text color={color}>{toolMessage}</Text>\n }\n\n // If the tool returns a React component, render it directly\n if (React.isValidElement(toolMessage)) {\n return (\n <Box flexDirection=\"row\">\n <Text color={color}>(</Text>\n {toolMessage}\n <Text color={color}>)</Text>\n </Box>\n )\n }\n\n // If it's a string, wrap it in Text\n return <Text color={color}>({toolMessage})</Text>\n })()}\n <Text color={color}>\u2026</Text>\n </Box>\n </Box>\n <Box flexDirection=\"column\" alignItems=\"flex-end\">\n <Cost costUSD={costUSD} durationMs={durationMs} debug={debug} />\n {/* Verbose mode: duration \u00B7 model \u00B7 time */}\n {verbose && (\n <Text color={VALUE_TIER_COLORS.meta}>\n {formatMetaInfo({\n duration: durationMs > 0 ? durationMs : undefined,\n model: modelId,\n timestamp: Date.now(),\n })}\n </Text>\n )}\n </Box>\n </Box>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import { Box, Text } from "ink";
3
3
  import { ParallelTasksGroupView } from "./ParallelTasksGroupView.js";
4
4
  import { TaskInModuleView } from "./TaskInModuleView.js";
5
+ import { SEMANTIC_COLORS } from "../../constants/colors.js";
5
6
  function GroupRenderer({
6
7
  group,
7
8
  context,
@@ -44,7 +45,7 @@ function GroupRenderer({
44
45
  );
45
46
  }
46
47
  default:
47
- return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "[Unknown group type: ", group.type, "]"));
48
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "[Unknown group type: ", group.type, "]"));
48
49
  }
49
50
  }
50
51
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/messages/GroupRenderer.tsx"],
4
- "sourcesContent": ["/**\n * Group Renderer Component\n *\n * Dispatches rendering to specialized components based on group type.\n * Entry point for the V1+ hierarchical message display system.\n */\n\nimport React from 'react'\nimport { Box, Text } from 'ink'\nimport type {\n ToolResultBlockParam,\n ToolUseBlockParam,\n} from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { MessageGroup, GroupContext } from '@minto-types/messageGroup'\nimport type { AgentTranscript } from '@utils/agentTranscripts'\nimport type { NormalizedMessage } from '@utils/messages'\nimport { ParallelTasksGroupView } from './ParallelTasksGroupView'\nimport { TaskInModuleView } from './TaskInModuleView'\n\ninterface Props {\n /** The group to render */\n group: MessageGroup\n /** Group rendering context */\n context: GroupContext\n /** Normalized messages */\n messages: NormalizedMessage[]\n /** Transcripts by agentId */\n transcripts: Map<string, AgentTranscript>\n /** Outputs by toolUseId */\n outputs: Map<string, ToolResultBlockParam>\n}\n\nexport function GroupRenderer({\n group,\n context,\n messages,\n transcripts,\n outputs,\n}: Props): React.ReactNode {\n const { displayConfig, shouldAnimate, getTranscript } = context\n\n switch (group.type) {\n case 'parallel-tasks':\n return (\n <ParallelTasksGroupView\n group={group}\n messages={messages}\n transcripts={transcripts}\n outputs={outputs}\n displayConfig={displayConfig}\n shouldAnimate={shouldAnimate}\n getTranscript={getTranscript}\n />\n )\n\n case 'task': {\n const toolUseId = group.metadata.toolUseId as string\n const agentId = group.metadata.agentId as string | undefined\n // Use getTranscript for lazy loading from disk (essential for historical messages)\n const transcript = agentId\n ? (getTranscript?.(agentId) ?? transcripts.get(agentId) ?? null)\n : null\n const output = outputs.get(toolUseId)\n\n return (\n <TaskInModuleView\n toolUseId={toolUseId}\n description={group.metadata.description || 'Task'}\n agentType={group.metadata.agentType || 'general-purpose'}\n transcript={transcript}\n output={output || null}\n config={displayConfig}\n shouldAnimate={shouldAnimate}\n inModule={false}\n />\n )\n }\n\n default:\n // Unknown type: render a simple placeholder\n return (\n <Box>\n <Text dimColor>[Unknown group type: {group.type}]</Text>\n </Box>\n )\n }\n}\n"],
5
- "mappings": "AAOA,OAAO,WAAW;AAClB,SAAS,KAAK,YAAY;AAQ1B,SAAS,8BAA8B;AACvC,SAAS,wBAAwB;AAe1B,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,EAAE,eAAe,eAAe,cAAc,IAAI;AAExD,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,IAGJ,KAAK,QAAQ;AACX,YAAM,YAAY,MAAM,SAAS;AACjC,YAAM,UAAU,MAAM,SAAS;AAE/B,YAAM,aAAa,UACd,gBAAgB,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,OACzD;AACJ,YAAM,SAAS,QAAQ,IAAI,SAAS;AAEpC,aACE;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,aAAa,MAAM,SAAS,eAAe;AAAA,UAC3C,WAAW,MAAM,SAAS,aAAa;AAAA,UACvC;AAAA,UACA,QAAQ,UAAU;AAAA,UAClB,QAAQ;AAAA,UACR;AAAA,UACA,UAAU;AAAA;AAAA,MACZ;AAAA,IAEJ;AAAA,IAEA;AAEE,aACE,oCAAC,WACC,oCAAC,QAAK,UAAQ,QAAC,yBAAsB,MAAM,MAAK,GAAC,CACnD;AAAA,EAEN;AACF;",
4
+ "sourcesContent": ["/**\n * Group Renderer Component\n *\n * Dispatches rendering to specialized components based on group type.\n * Entry point for the V1+ hierarchical message display system.\n */\n\nimport React from 'react'\nimport { Box, Text } from 'ink'\nimport type {\n ToolResultBlockParam,\n ToolUseBlockParam,\n} from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { MessageGroup, GroupContext } from '@minto-types/messageGroup'\nimport type { AgentTranscript } from '@utils/agentTranscripts'\nimport type { NormalizedMessage } from '@utils/messages'\nimport { ParallelTasksGroupView } from './ParallelTasksGroupView'\nimport { TaskInModuleView } from './TaskInModuleView'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\ninterface Props {\n /** The group to render */\n group: MessageGroup\n /** Group rendering context */\n context: GroupContext\n /** Normalized messages */\n messages: NormalizedMessage[]\n /** Transcripts by agentId */\n transcripts: Map<string, AgentTranscript>\n /** Outputs by toolUseId */\n outputs: Map<string, ToolResultBlockParam>\n}\n\nexport function GroupRenderer({\n group,\n context,\n messages,\n transcripts,\n outputs,\n}: Props): React.ReactNode {\n const { displayConfig, shouldAnimate, getTranscript } = context\n\n switch (group.type) {\n case 'parallel-tasks':\n return (\n <ParallelTasksGroupView\n group={group}\n messages={messages}\n transcripts={transcripts}\n outputs={outputs}\n displayConfig={displayConfig}\n shouldAnimate={shouldAnimate}\n getTranscript={getTranscript}\n />\n )\n\n case 'task': {\n const toolUseId = group.metadata.toolUseId as string\n const agentId = group.metadata.agentId as string | undefined\n // Use getTranscript for lazy loading from disk (essential for historical messages)\n const transcript = agentId\n ? (getTranscript?.(agentId) ?? transcripts.get(agentId) ?? null)\n : null\n const output = outputs.get(toolUseId)\n\n return (\n <TaskInModuleView\n toolUseId={toolUseId}\n description={group.metadata.description || 'Task'}\n agentType={group.metadata.agentType || 'general-purpose'}\n transcript={transcript}\n output={output || null}\n config={displayConfig}\n shouldAnimate={shouldAnimate}\n inModule={false}\n />\n )\n }\n\n default:\n // Unknown type: render a simple placeholder\n return (\n <Box>\n <Text color={SEMANTIC_COLORS.dim}>\n [Unknown group type: {group.type}]\n </Text>\n </Box>\n )\n }\n}\n"],
5
+ "mappings": "AAOA,OAAO,WAAW;AAClB,SAAS,KAAK,YAAY;AAQ1B,SAAS,8BAA8B;AACvC,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAezB,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,EAAE,eAAe,eAAe,cAAc,IAAI;AAExD,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,IAGJ,KAAK,QAAQ;AACX,YAAM,YAAY,MAAM,SAAS;AACjC,YAAM,UAAU,MAAM,SAAS;AAE/B,YAAM,aAAa,UACd,gBAAgB,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,OACzD;AACJ,YAAM,SAAS,QAAQ,IAAI,SAAS;AAEpC,aACE;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,aAAa,MAAM,SAAS,eAAe;AAAA,UAC3C,WAAW,MAAM,SAAS,aAAa;AAAA,UACvC;AAAA,UACA,QAAQ,UAAU;AAAA,UAClB,QAAQ;AAAA,UACR;AAAA,UACA,UAAU;AAAA;AAAA,MACZ;AAAA,IAEJ;AAAA,IAEA;AAEE,aACE,oCAAC,WACC,oCAAC,QAAK,OAAO,gBAAgB,OAAK,yBACV,MAAM,MAAK,GACnC,CACF;AAAA,EAEN;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,10 +1,22 @@
1
1
  import React from "react";
2
2
  import { Box, Text } from "ink";
3
+ import {
4
+ SEMANTIC_COLORS,
5
+ SYMBOL_COLORS,
6
+ STATUS_COLORS
7
+ } from "../../constants/colors.js";
3
8
  function NestedTasksPreview({
4
9
  tasks,
5
10
  hiddenCount
6
11
  }) {
7
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, hiddenCount > 0 && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\xB7\xB7\xB7 ", hiddenCount, " earlier tasks hidden \xB7\xB7\xB7"), tasks.map((child, i) => /* @__PURE__ */ React.createElement(Box, { key: i, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, child.status === "completed" ? "\u2713" : "\u22EF", " "), /* @__PURE__ */ React.createElement(Text, null, child.description)), child.content && /* @__PURE__ */ React.createElement(Box, { marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, child.content)))));
12
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, hiddenCount > 0 && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "\xB7\xB7\xB7 ", hiddenCount, " earlier tasks hidden \xB7\xB7\xB7"), tasks.map((child, i) => /* @__PURE__ */ React.createElement(Box, { key: i, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(
13
+ Text,
14
+ {
15
+ color: child.status === "completed" ? SYMBOL_COLORS.success : STATUS_COLORS.running
16
+ },
17
+ child.status === "completed" ? "\u2713" : "\u22EF",
18
+ " "
19
+ ), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.secondary }, child.description)), child.content && /* @__PURE__ */ React.createElement(Box, { marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, child.content)))));
8
20
  }
9
21
  export {
10
22
  NestedTasksPreview
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/messages/NestedTasksPreview.tsx"],
4
- "sourcesContent": ["/**\n * Nested Tasks Preview Component\n *\n * Displays a preview of nested/child tasks with status and content.\n * Used for intermediate state display during task execution.\n */\n\nimport React from 'react'\nimport { Box, Text } from 'ink'\n\ninterface NestedTaskChild {\n description: string\n status: string\n content: string\n}\n\ninterface Props {\n tasks: NestedTaskChild[]\n hiddenCount: number\n}\n\nexport function NestedTasksPreview({\n tasks,\n hiddenCount,\n}: Props): React.ReactNode {\n return (\n <Box flexDirection=\"column\">\n {/* Hidden tasks indicator */}\n {hiddenCount > 0 && (\n <Text dimColor>\u00B7\u00B7\u00B7 {hiddenCount} earlier tasks hidden \u00B7\u00B7\u00B7</Text>\n )}\n\n {/* Visible nested tasks */}\n {tasks.map((child, i) => (\n <Box key={i} flexDirection=\"column\">\n <Text>\n <Text dimColor>{child.status === 'completed' ? '\u2713' : '\u22EF'} </Text>\n <Text>{child.description}</Text>\n </Text>\n {child.content && (\n <Box marginLeft={2}>\n <Text dimColor>{child.content}</Text>\n </Box>\n )}\n </Box>\n ))}\n </Box>\n )\n}\n"],
5
- "mappings": "AAOA,OAAO,WAAW;AAClB,SAAS,KAAK,YAAY;AAanB,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAA2B;AACzB,SACE,oCAAC,OAAI,eAAc,YAEhB,cAAc,KACb,oCAAC,QAAK,UAAQ,QAAC,iBAAK,aAAY,oCAAyB,GAI1D,MAAM,IAAI,CAAC,OAAO,MACjB,oCAAC,OAAI,KAAK,GAAG,eAAc,YACzB,oCAAC,YACC,oCAAC,QAAK,UAAQ,QAAE,MAAM,WAAW,cAAc,WAAM,UAAI,GAAC,GAC1D,oCAAC,YAAM,MAAM,WAAY,CAC3B,GACC,MAAM,WACL,oCAAC,OAAI,YAAY,KACf,oCAAC,QAAK,UAAQ,QAAE,MAAM,OAAQ,CAChC,CAEJ,CACD,CACH;AAEJ;",
4
+ "sourcesContent": ["/**\n * Nested Tasks Preview Component\n *\n * Displays a preview of nested/child tasks with status and content.\n * Used for intermediate state display during task execution.\n */\n\nimport React from 'react'\nimport { Box, Text } from 'ink'\nimport {\n SEMANTIC_COLORS,\n SYMBOL_COLORS,\n STATUS_COLORS,\n} from '@constants/colors'\n\ninterface NestedTaskChild {\n description: string\n status: string\n content: string\n}\n\ninterface Props {\n tasks: NestedTaskChild[]\n hiddenCount: number\n}\n\nexport function NestedTasksPreview({\n tasks,\n hiddenCount,\n}: Props): React.ReactNode {\n return (\n <Box flexDirection=\"column\">\n {/* Hidden tasks indicator */}\n {hiddenCount > 0 && (\n <Text color={SEMANTIC_COLORS.dim}>\n \u00B7\u00B7\u00B7 {hiddenCount} earlier tasks hidden \u00B7\u00B7\u00B7\n </Text>\n )}\n\n {/* Visible nested tasks */}\n {tasks.map((child, i) => (\n <Box key={i} flexDirection=\"column\">\n <Text>\n <Text\n color={\n child.status === 'completed'\n ? SYMBOL_COLORS.success\n : STATUS_COLORS.running\n }\n >\n {child.status === 'completed' ? '\u2713' : '\u22EF'}{' '}\n </Text>\n <Text color={SEMANTIC_COLORS.secondary}>{child.description}</Text>\n </Text>\n {child.content && (\n <Box marginLeft={2}>\n <Text color={SEMANTIC_COLORS.dim}>{child.content}</Text>\n </Box>\n )}\n </Box>\n ))}\n </Box>\n )\n}\n"],
5
+ "mappings": "AAOA,OAAO,WAAW;AAClB,SAAS,KAAK,YAAY;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAaA,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAA2B;AACzB,SACE,oCAAC,OAAI,eAAc,YAEhB,cAAc,KACb,oCAAC,QAAK,OAAO,gBAAgB,OAAK,iBAC3B,aAAY,oCACnB,GAID,MAAM,IAAI,CAAC,OAAO,MACjB,oCAAC,OAAI,KAAK,GAAG,eAAc,YACzB,oCAAC,YACC;AAAA,IAAC;AAAA;AAAA,MACC,OACE,MAAM,WAAW,cACb,cAAc,UACd,cAAc;AAAA;AAAA,IAGnB,MAAM,WAAW,cAAc,WAAM;AAAA,IAAK;AAAA,EAC7C,GACA,oCAAC,QAAK,OAAO,gBAAgB,aAAY,MAAM,WAAY,CAC7D,GACC,MAAM,WACL,oCAAC,OAAI,YAAY,KACf,oCAAC,QAAK,OAAO,gBAAgB,OAAM,MAAM,OAAQ,CACnD,CAEJ,CACD,CACH;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -8,7 +8,8 @@ import { MARGIN_BEFORE_MODULE, INDENT_LEVELS } from "../../constants/formatRules
8
8
  import { SYMBOLS } from "../../constants/symbols.js";
9
9
  import {
10
10
  SEMANTIC_COLORS,
11
- VALUE_TIER_COLORS
11
+ VALUE_TIER_COLORS,
12
+ SYMBOL_COLORS
12
13
  } from "../../constants/colors.js";
13
14
  import { formatMetaInfo } from "../../utils/taskDisplayUtils.js";
14
15
  function ParallelTasksGroupView({
@@ -34,7 +35,7 @@ function ParallelTasksGroupView({
34
35
  }).length;
35
36
  const totalCount = memberInfos.length;
36
37
  const isCompleted = completedCount === totalCount && totalCount > 0;
37
- const statusColor = isCompleted ? SEMANTIC_COLORS.success : group.status === "running" ? SEMANTIC_COLORS.running : SEMANTIC_COLORS.dim;
38
+ const statusColor = isCompleted ? SYMBOL_COLORS.success : group.status === "running" ? SYMBOL_COLORS.running : SYMBOL_COLORS.pending;
38
39
  const groupSymbol = isCompleted ? SYMBOLS.TOOL_SUCCESS : SYMBOLS.PARALLEL_GROUP;
39
40
  const groupMetaInfo = (() => {
40
41
  if (!isCompleted) return null;
@@ -58,7 +59,7 @@ function ParallelTasksGroupView({
58
59
  timestamp: latestEnd
59
60
  };
60
61
  })();
61
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: "100%", marginTop: MARGIN_BEFORE_MODULE }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: statusColor }, groupSymbol, " "), /* @__PURE__ */ React.createElement(Text, { bold: true, color: SEMANTIC_COLORS.secondary }, "Parallel Tasks"), /* @__PURE__ */ React.createElement(Text, null, " "), /* @__PURE__ */ React.createElement(Text, null, "("), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.success }, completedCount), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "/", totalCount), /* @__PURE__ */ React.createElement(Text, null, " finished)"), displayConfig.showMetaInfo && groupMetaInfo && /* @__PURE__ */ React.createElement(Text, { color: VALUE_TIER_COLORS.meta }, " ", formatMetaInfo({
62
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: "100%", marginTop: MARGIN_BEFORE_MODULE }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: statusColor }, groupSymbol, " "), /* @__PURE__ */ React.createElement(Text, { bold: true, color: SEMANTIC_COLORS.secondary }, "Parallel Tasks"), /* @__PURE__ */ React.createElement(Text, null, " "), /* @__PURE__ */ React.createElement(Text, null, "("), /* @__PURE__ */ React.createElement(Text, { color: SYMBOL_COLORS.success }, completedCount), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "/", totalCount), /* @__PURE__ */ React.createElement(Text, null, " finished)"), displayConfig.showMetaInfo && groupMetaInfo && /* @__PURE__ */ React.createElement(Text, { color: VALUE_TIER_COLORS.meta }, " ", formatMetaInfo({
62
63
  duration: groupMetaInfo.duration,
63
64
  timestamp: groupMetaInfo.timestamp
64
65
  })), /* @__PURE__ */ React.createElement(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/messages/ParallelTasksGroupView.tsx"],
4
- "sourcesContent": ["/**\n * Parallel Tasks Group View\n *\n * Renders a group of concurrent tasks as a unified module.\n * Displays completion progress and individual task status.\n */\n\nimport React from 'react'\nimport { Box, Text } from 'ink'\nimport type { ToolResultBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { MessageGroup, DisplayConfig } from '@minto-types/messageGroup'\nimport type { AgentTranscript } from '@utils/agentTranscripts'\nimport type { NormalizedMessage } from '@utils/messages'\nimport { ToolUseLoader } from '@components/ToolUseLoader'\nimport { TreeConnector, TreeContinuation } from '@components/TreeConnector'\nimport { CollapsibleHint } from '@components/CollapsibleHint'\nimport { TaskInModuleView } from './TaskInModuleView'\nimport { ParallelTasksHandler } from '@utils/groupHandlers/parallelTasksHandler'\nimport { MARGIN_BEFORE_MODULE, INDENT_LEVELS } from '@constants/formatRules'\nimport { SYMBOLS } from '@constants/symbols'\nimport {\n SEMANTIC_COLORS,\n STATUS_COLORS,\n VALUE_TIER_COLORS,\n} from '@constants/colors'\nimport { formatMetaInfo } from '@utils/taskDisplayUtils'\n\ninterface Props {\n /** The parallel tasks group */\n group: MessageGroup\n /** Normalized messages for looking up task info */\n messages: NormalizedMessage[]\n /** Transcripts by agentId */\n transcripts: Map<string, AgentTranscript>\n /** Outputs by toolUseId */\n outputs: Map<string, ToolResultBlockParam>\n /** Display configuration */\n displayConfig: DisplayConfig\n /** Whether to animate */\n shouldAnimate: boolean\n /**\n * Function to get transcript by agentId with lazy loading from disk.\n * Essential for loading historical transcripts that aren't in memory.\n */\n getTranscript?: (agentId: string) => AgentTranscript | null\n}\n\nexport function ParallelTasksGroupView({\n group,\n messages,\n transcripts,\n outputs,\n displayConfig,\n shouldAnimate,\n getTranscript,\n}: Props): React.ReactNode {\n const memberIds = (group.metadata.siblingToolUseIds as string[]) || []\n\n // Helper to get transcript - use getTranscript for lazy loading, fallback to Map\n const getTranscriptForAgent = (agentId: string): AgentTranscript | null => {\n return getTranscript?.(agentId) ?? transcripts.get(agentId) ?? null\n }\n\n // Get task info for each member\n const memberInfos = ParallelTasksHandler.getMemberTaskInfo(group, messages)\n\n // Count completions - check both transcript status AND output existence\n const completedCount = memberInfos.filter(info => {\n // Check if output exists (definitive completion signal)\n const output = outputs.get(info.toolUseId)\n if (output) return true\n\n // Fallback to transcript status\n if (!info.agentId) return false\n const transcript = getTranscriptForAgent(info.agentId)\n return transcript?.status === 'completed'\n }).length\n\n const totalCount = memberInfos.length\n\n // Determine completion status - use actual completion count as primary signal\n // This is more reliable than group.status which may have timing issues\n const isCompleted = completedCount === totalCount && totalCount > 0\n\n // \u4F7F\u7528 REPL \u89C4\u8303\u5B9A\u4E49\u7684\u8BED\u4E49\u989C\u8272\n const statusColor = isCompleted\n ? SEMANTIC_COLORS.success\n : group.status === 'running'\n ? SEMANTIC_COLORS.running\n : SEMANTIC_COLORS.dim\n\n // \u4F7F\u7528 REPL \u89C4\u8303\u5B9A\u4E49\u7684\u7B26\u53F7\uFF1A\u5E76\u884C\u4EFB\u52A1\u7EC4 \u25C8\n const groupSymbol = isCompleted\n ? SYMBOLS.TOOL_SUCCESS\n : SYMBOLS.PARALLEL_GROUP\n\n // \u8BA1\u7B97\u7EC4\u7EA7\u522B\u7684\u5143\u4FE1\u606F\uFF08\u7528\u4E8E verbose \u6A21\u5F0F\uFF09\n const groupMetaInfo = (() => {\n if (!isCompleted) return null\n\n // \u83B7\u53D6\u6240\u6709\u5DF2\u5B8C\u6210\u4EFB\u52A1\u7684 transcript\n const completedTranscripts: AgentTranscript[] = []\n for (const info of memberInfos) {\n if (info.agentId) {\n const transcript = getTranscriptForAgent(info.agentId)\n if (transcript?.endTime) {\n completedTranscripts.push(transcript)\n }\n }\n }\n\n if (completedTranscripts.length === 0) return null\n\n // \u8BA1\u7B97\u603B\u8017\u65F6\uFF08\u4ECE\u6700\u65E9\u5F00\u59CB\u5230\u6700\u665A\u7ED3\u675F\uFF09\n const startTimes = completedTranscripts.map(t => t.startTime)\n const endTimes = completedTranscripts.map(t => t.endTime!)\n const earliestStart = Math.min(...startTimes)\n const latestEnd = Math.max(...endTimes)\n const totalDuration = latestEnd - earliestStart\n\n return {\n duration: totalDuration,\n timestamp: latestEnd,\n }\n })()\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" marginTop={MARGIN_BEFORE_MODULE}>\n {/* Module header - \u4F7F\u7528 REPL \u89C4\u8303\u7B26\u53F7 */}\n <Box flexDirection=\"row\">\n {/* \u4F7F\u7528 \u25C8 \u4F5C\u4E3A\u5E76\u884C\u4EFB\u52A1\u7EC4\u7B26\u53F7\uFF0C\u5B8C\u6210\u65F6\u4F7F\u7528 \u2713 */}\n <Text color={statusColor}>{groupSymbol} </Text>\n <Text bold color={SEMANTIC_COLORS.secondary}>\n Parallel Tasks\n </Text>\n <Text> </Text>\n {/* \u8FDB\u5EA6\u6570\u5B57\uFF1A\u5B8C\u6210\u6570\u7528 success \u8272\uFF0C\u603B\u6570\u7528 dim \u8272 */}\n <Text>(</Text>\n <Text color={SEMANTIC_COLORS.success}>{completedCount}</Text>\n <Text color={SEMANTIC_COLORS.dim}>/{totalCount}</Text>\n <Text> finished)</Text>\n {/* Verbose mode: \u663E\u793A\u7EC4\u7EA7\u522B\u7684\u5143\u4FE1\u606F */}\n {displayConfig.showMetaInfo && groupMetaInfo && (\n <Text color={VALUE_TIER_COLORS.meta}>\n {' '}\n {formatMetaInfo({\n duration: groupMetaInfo.duration,\n timestamp: groupMetaInfo.timestamp,\n })}\n </Text>\n )}\n {/* Show expand hint in normal mode when completed */}\n <CollapsibleHint\n canExpand={isCompleted && !displayConfig.showAllChildren}\n />\n </Box>\n\n {/* Member tasks - \u4F7F\u7528 REPL \u89C4\u8303\u5B9A\u4E49\u7684\u7F29\u8FDB\u5C42\u7EA7 L1 */}\n <Box flexDirection=\"column\" marginLeft={INDENT_LEVELS.L1}>\n {memberInfos.map((info, index) => {\n const isLast = index === memberInfos.length - 1\n const transcript = info.agentId\n ? getTranscriptForAgent(info.agentId)\n : null\n const output = outputs.get(info.toolUseId)\n\n return (\n <Box key={info.toolUseId} flexDirection=\"row\">\n {/* Tree connector */}\n <TreeConnector isLast={isLast} />\n\n {/* Task content */}\n <TaskInModuleView\n toolUseId={info.toolUseId}\n description={info.description}\n agentType={info.agentType}\n transcript={transcript}\n output={output || null}\n config={displayConfig}\n shouldAnimate={shouldAnimate}\n inModule={true}\n isLastInModule={isLast}\n />\n </Box>\n )\n })}\n </Box>\n </Box>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Parallel Tasks Group View\n *\n * Renders a group of concurrent tasks as a unified module.\n * Displays completion progress and individual task status.\n */\n\nimport React from 'react'\nimport { Box, Text } from 'ink'\nimport type { ToolResultBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { MessageGroup, DisplayConfig } from '@minto-types/messageGroup'\nimport type { AgentTranscript } from '@utils/agentTranscripts'\nimport type { NormalizedMessage } from '@utils/messages'\nimport { ToolUseLoader } from '@components/ToolUseLoader'\nimport { TreeConnector, TreeContinuation } from '@components/TreeConnector'\nimport { CollapsibleHint } from '@components/CollapsibleHint'\nimport { TaskInModuleView } from './TaskInModuleView'\nimport { ParallelTasksHandler } from '@utils/groupHandlers/parallelTasksHandler'\nimport { MARGIN_BEFORE_MODULE, INDENT_LEVELS } from '@constants/formatRules'\nimport { SYMBOLS } from '@constants/symbols'\nimport {\n SEMANTIC_COLORS,\n STATUS_COLORS,\n VALUE_TIER_COLORS,\n SYMBOL_COLORS,\n} from '@constants/colors'\nimport { formatMetaInfo } from '@utils/taskDisplayUtils'\n\ninterface Props {\n /** The parallel tasks group */\n group: MessageGroup\n /** Normalized messages for looking up task info */\n messages: NormalizedMessage[]\n /** Transcripts by agentId */\n transcripts: Map<string, AgentTranscript>\n /** Outputs by toolUseId */\n outputs: Map<string, ToolResultBlockParam>\n /** Display configuration */\n displayConfig: DisplayConfig\n /** Whether to animate */\n shouldAnimate: boolean\n /**\n * Function to get transcript by agentId with lazy loading from disk.\n * Essential for loading historical transcripts that aren't in memory.\n */\n getTranscript?: (agentId: string) => AgentTranscript | null\n}\n\nexport function ParallelTasksGroupView({\n group,\n messages,\n transcripts,\n outputs,\n displayConfig,\n shouldAnimate,\n getTranscript,\n}: Props): React.ReactNode {\n const memberIds = (group.metadata.siblingToolUseIds as string[]) || []\n\n // Helper to get transcript - use getTranscript for lazy loading, fallback to Map\n const getTranscriptForAgent = (agentId: string): AgentTranscript | null => {\n return getTranscript?.(agentId) ?? transcripts.get(agentId) ?? null\n }\n\n // Get task info for each member\n const memberInfos = ParallelTasksHandler.getMemberTaskInfo(group, messages)\n\n // Count completions - check both transcript status AND output existence\n const completedCount = memberInfos.filter(info => {\n // Check if output exists (definitive completion signal)\n const output = outputs.get(info.toolUseId)\n if (output) return true\n\n // Fallback to transcript status\n if (!info.agentId) return false\n const transcript = getTranscriptForAgent(info.agentId)\n return transcript?.status === 'completed'\n }).length\n\n const totalCount = memberInfos.length\n\n // Determine completion status - use actual completion count as primary signal\n // This is more reliable than group.status which may have timing issues\n const isCompleted = completedCount === totalCount && totalCount > 0\n\n // \u4F7F\u7528 SYMBOL_COLORS \u4E0E Logo \u54C1\u724C\u914D\u8272\u4FDD\u6301\u4E00\u81F4\n const statusColor = isCompleted\n ? SYMBOL_COLORS.success\n : group.status === 'running'\n ? SYMBOL_COLORS.running\n : SYMBOL_COLORS.pending\n\n // \u4F7F\u7528 REPL \u89C4\u8303\u5B9A\u4E49\u7684\u7B26\u53F7\uFF1A\u5E76\u884C\u4EFB\u52A1\u7EC4 \u25C8\n const groupSymbol = isCompleted\n ? SYMBOLS.TOOL_SUCCESS\n : SYMBOLS.PARALLEL_GROUP\n\n // \u8BA1\u7B97\u7EC4\u7EA7\u522B\u7684\u5143\u4FE1\u606F\uFF08\u7528\u4E8E verbose \u6A21\u5F0F\uFF09\n const groupMetaInfo = (() => {\n if (!isCompleted) return null\n\n // \u83B7\u53D6\u6240\u6709\u5DF2\u5B8C\u6210\u4EFB\u52A1\u7684 transcript\n const completedTranscripts: AgentTranscript[] = []\n for (const info of memberInfos) {\n if (info.agentId) {\n const transcript = getTranscriptForAgent(info.agentId)\n if (transcript?.endTime) {\n completedTranscripts.push(transcript)\n }\n }\n }\n\n if (completedTranscripts.length === 0) return null\n\n // \u8BA1\u7B97\u603B\u8017\u65F6\uFF08\u4ECE\u6700\u65E9\u5F00\u59CB\u5230\u6700\u665A\u7ED3\u675F\uFF09\n const startTimes = completedTranscripts.map(t => t.startTime)\n const endTimes = completedTranscripts.map(t => t.endTime!)\n const earliestStart = Math.min(...startTimes)\n const latestEnd = Math.max(...endTimes)\n const totalDuration = latestEnd - earliestStart\n\n return {\n duration: totalDuration,\n timestamp: latestEnd,\n }\n })()\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" marginTop={MARGIN_BEFORE_MODULE}>\n {/* Module header - \u4F7F\u7528 REPL \u89C4\u8303\u7B26\u53F7 */}\n <Box flexDirection=\"row\">\n {/* \u4F7F\u7528 \u25C8 \u4F5C\u4E3A\u5E76\u884C\u4EFB\u52A1\u7EC4\u7B26\u53F7\uFF0C\u5B8C\u6210\u65F6\u4F7F\u7528 \u2713 */}\n <Text color={statusColor}>{groupSymbol} </Text>\n <Text bold color={SEMANTIC_COLORS.secondary}>\n Parallel Tasks\n </Text>\n <Text> </Text>\n {/* \u8FDB\u5EA6\u6570\u5B57\uFF1A\u5B8C\u6210\u6570\u7528 success \u8272\uFF0C\u603B\u6570\u7528 dim \u8272 */}\n <Text>(</Text>\n <Text color={SYMBOL_COLORS.success}>{completedCount}</Text>\n <Text color={SEMANTIC_COLORS.dim}>/{totalCount}</Text>\n <Text> finished)</Text>\n {/* Verbose mode: \u663E\u793A\u7EC4\u7EA7\u522B\u7684\u5143\u4FE1\u606F */}\n {displayConfig.showMetaInfo && groupMetaInfo && (\n <Text color={VALUE_TIER_COLORS.meta}>\n {' '}\n {formatMetaInfo({\n duration: groupMetaInfo.duration,\n timestamp: groupMetaInfo.timestamp,\n })}\n </Text>\n )}\n {/* Show expand hint in normal mode when completed */}\n <CollapsibleHint\n canExpand={isCompleted && !displayConfig.showAllChildren}\n />\n </Box>\n\n {/* Member tasks - \u4F7F\u7528 REPL \u89C4\u8303\u5B9A\u4E49\u7684\u7F29\u8FDB\u5C42\u7EA7 L1 */}\n <Box flexDirection=\"column\" marginLeft={INDENT_LEVELS.L1}>\n {memberInfos.map((info, index) => {\n const isLast = index === memberInfos.length - 1\n const transcript = info.agentId\n ? getTranscriptForAgent(info.agentId)\n : null\n const output = outputs.get(info.toolUseId)\n\n return (\n <Box key={info.toolUseId} flexDirection=\"row\">\n {/* Tree connector */}\n <TreeConnector isLast={isLast} />\n\n {/* Task content */}\n <TaskInModuleView\n toolUseId={info.toolUseId}\n description={info.description}\n agentType={info.agentType}\n transcript={transcript}\n output={output || null}\n config={displayConfig}\n shouldAnimate={shouldAnimate}\n inModule={true}\n isLastInModule={isLast}\n />\n </Box>\n )\n })}\n </Box>\n </Box>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -20,7 +20,8 @@ import { formatStats, formatCount } from "../../constants/formatRules.js";
20
20
  import { SYMBOLS } from "../../constants/symbols.js";
21
21
  import {
22
22
  SEMANTIC_COLORS,
23
- VALUE_TIER_COLORS
23
+ VALUE_TIER_COLORS,
24
+ SYMBOL_COLORS
24
25
  } from "../../constants/colors.js";
25
26
  function formatTokens(count) {
26
27
  if (count >= 1e3) {
@@ -28,6 +29,16 @@ function formatTokens(count) {
28
29
  }
29
30
  return String(count);
30
31
  }
32
+ function formatBidirectionalTokens(inputTokens, outputTokens) {
33
+ const parts = [];
34
+ if (inputTokens > 0) {
35
+ parts.push(`\u2191${formatTokens(inputTokens)}`);
36
+ }
37
+ if (outputTokens > 0) {
38
+ parts.push(`\u2193${formatTokens(outputTokens)}`);
39
+ }
40
+ return parts.join(" ");
41
+ }
31
42
  function ToolUseHistoryDisplay({
32
43
  transcript,
33
44
  config,
@@ -47,27 +58,27 @@ function ToolUseHistoryDisplay({
47
58
  const renderRow = (key, content) => /* @__PURE__ */ React.createElement(Box, { key, flexDirection: "row" }, inModule && /* @__PURE__ */ React.createElement(TreeContinuation, { parentIsLast: isLastInModule }), !inModule && /* @__PURE__ */ React.createElement(Box, { minWidth: 4 }), content);
48
59
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, hiddenCount > 0 && renderRow(
49
60
  "hidden-count",
50
- /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "... ", hiddenCount, " earlier tools hidden")
61
+ /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "... ", hiddenCount, " earlier tools hidden")
51
62
  ), tools.map((tool) => {
52
63
  const displayName = getToolDisplayName(tool.name);
53
64
  const description = truncate(tool.description, maxDescChars);
54
65
  return renderRow(
55
66
  tool.id,
56
- /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, tool.isExecuting ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.running }, SYMBOLS.TOOL_RUNNING, " ") : /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, SYMBOLS.CHILD_OUTPUT, " "), /* @__PURE__ */ React.createElement(
67
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, tool.isExecuting ? /* @__PURE__ */ React.createElement(Text, { color: SYMBOL_COLORS.running }, SYMBOLS.TOOL_RUNNING, " ") : /* @__PURE__ */ React.createElement(Text, { color: SYMBOL_COLORS.child }, SYMBOLS.CHILD_OUTPUT, " "), /* @__PURE__ */ React.createElement(
57
68
  Text,
58
69
  {
59
- color: tool.isExecuting ? SEMANTIC_COLORS.running : SEMANTIC_COLORS.secondary
70
+ color: tool.isExecuting ? SYMBOL_COLORS.running : SEMANTIC_COLORS.secondary
60
71
  },
61
72
  displayName
62
73
  ), description && /* @__PURE__ */ React.createElement(
63
74
  Text,
64
75
  {
65
- color: tool.isExecuting ? SEMANTIC_COLORS.running : SEMANTIC_COLORS.dim
76
+ color: tool.isExecuting ? SYMBOL_COLORS.running : SEMANTIC_COLORS.dim
66
77
  },
67
78
  "(",
68
79
  description,
69
80
  ")"
70
- ), tool.isExecuting && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.running }, SYMBOLS.SUFFIX_RUNNING))
81
+ ), tool.isExecuting && /* @__PURE__ */ React.createElement(Text, { color: SYMBOL_COLORS.running }, SYMBOLS.SUFFIX_RUNNING))
71
82
  );
72
83
  }));
73
84
  }
@@ -139,10 +150,13 @@ function TaskInModuleView({
139
150
  timestamp: transcript.endTime
140
151
  }), transcript.toolUseCount > 0 && ` \xB7 ${formatCount(transcript.toolUseCount, "tool")}`, ")")
141
152
  ) : (
142
- // Normal mode: 简洁显示
143
- /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " ", "(", formatStats([
153
+ // Normal mode: compact stats with bidirectional tokens
154
+ /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "(", formatStats([
144
155
  formatCount(transcript.toolUseCount, "tool"),
145
- `${formatTokens(totalTokens)} tokens`,
156
+ formatBidirectionalTokens(
157
+ transcript.tokenUsage.inputTokens,
158
+ transcript.tokenUsage.outputTokens
159
+ ),
146
160
  duration
147
161
  ]), ")")
148
162
  )), inModule && status === "running" && transcript && /* @__PURE__ */ React.createElement(Text, { color: VALUE_TIER_COLORS.meta }, " ", "(", config.showMetaInfo ? formatMetaInfo({
@@ -151,9 +165,12 @@ function TaskInModuleView({
151
165
  }) : formatStats([
152
166
  transcript.toolUseCount > 0 ? formatCount(transcript.toolUseCount, "tool") : null,
153
167
  duration,
154
- // Show output tokens with indicator (tokens being received)
155
- transcript.tokenUsage.outputTokens > 0 ? `\u2193 ${formatTokens(transcript.tokenUsage.outputTokens)} tokens` : null
156
- ]), ")"), !inModule && transcript && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " [", transcript.agentId.slice(0, 8), "]")), !inModule && transcript && /* @__PURE__ */ React.createElement(Box, { marginLeft: 4 }, config.showMetaInfo ? (
168
+ // Show bidirectional tokens: ↑inputoutput
169
+ formatBidirectionalTokens(
170
+ transcript.tokenUsage.inputTokens,
171
+ transcript.tokenUsage.outputTokens
172
+ ) || null
173
+ ]), ")"), !inModule && transcript && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "[", transcript.agentId.slice(0, 8), "]")), !inModule && transcript && /* @__PURE__ */ React.createElement(Box, { marginLeft: 4 }, config.showMetaInfo ? (
157
174
  // Verbose mode: 使用元信息格式 "耗时 · 模型 · 时间"
158
175
  /* @__PURE__ */ React.createElement(Text, { color: VALUE_TIER_COLORS.meta }, status === "completed" ? "\u2713" : "\u22EF", " ", formatMetaInfo({
159
176
  duration: transcript.endTime ? transcript.endTime - transcript.startTime : void 0,
@@ -161,8 +178,11 @@ function TaskInModuleView({
161
178
  timestamp: transcript.endTime || Date.now()
162
179
  }), " \xB7 ", "Tools: ", transcript.toolUseCount, " \xB7 Tokens:", " ", formatTokens(totalTokens))
163
180
  ) : (
164
- // Normal mode: 简洁显示
165
- /* @__PURE__ */ React.createElement(Text, { dimColor: true }, status === "completed" ? "\u2713" : "\u22EF", " Tools:", " ", transcript.toolUseCount, " | Tokens: ", formatTokens(totalTokens), duration ? ` | ${duration}` : "")
181
+ // Normal mode: compact display with bidirectional tokens
182
+ /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, status === "completed" ? "\u2713" : "\u22EF", " Tools:", " ", transcript.toolUseCount, " |", " ", formatBidirectionalTokens(
183
+ transcript.tokenUsage.inputTokens,
184
+ transcript.tokenUsage.outputTokens
185
+ ), duration ? ` | ${duration}` : "")
166
186
  )), transcript && /* @__PURE__ */ React.createElement(
167
187
  ToolUseHistoryDisplay,
168
188
  {
@@ -180,7 +200,7 @@ function TaskInModuleView({
180
200
  }
181
201
  ))), output && isCompleted && /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, inModule && /* @__PURE__ */ React.createElement(TreeContinuation, { parentIsLast: isLastInModule }), !inModule && /* @__PURE__ */ React.createElement(Box, { minWidth: 4 }), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, config.showAllChildren ? (
182
202
  // Verbose mode: show full output with header
183
- /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Output \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"), /* @__PURE__ */ React.createElement(Box, { marginLeft: 2 }, /* @__PURE__ */ React.createElement(TaskOutputContent, { content: output.content })))
203
+ /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Output \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"), /* @__PURE__ */ React.createElement(Box, { marginLeft: 2 }, /* @__PURE__ */ React.createElement(TaskOutputContent, { content: output.content })))
184
204
  ) : (
185
205
  // Normal mode: show compact summary with expand hint
186
206
  /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(