@within-7/minto 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (481) hide show
  1. package/cli.js +155 -37
  2. package/dist/Tool.js +38 -0
  3. package/dist/Tool.js.map +3 -3
  4. package/dist/commands/agents/AgentsCommand.js +52 -26
  5. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  6. package/dist/commands/agents/constants.js +1 -1
  7. package/dist/commands/agents/constants.js.map +1 -1
  8. package/dist/commands/agents/index.js +1 -1
  9. package/dist/commands/bug.js +74 -7
  10. package/dist/commands/bug.js.map +3 -3
  11. package/dist/commands/clear.js +3 -0
  12. package/dist/commands/clear.js.map +2 -2
  13. package/dist/commands/compact.js +37 -0
  14. package/dist/commands/compact.js.map +2 -2
  15. package/dist/commands/context.js +84 -0
  16. package/dist/commands/context.js.map +7 -0
  17. package/dist/commands/ctx_viz.js +18 -10
  18. package/dist/commands/ctx_viz.js.map +2 -2
  19. package/dist/commands/doctor.js +158 -12
  20. package/dist/commands/doctor.js.map +2 -2
  21. package/dist/commands/export.js +156 -0
  22. package/dist/commands/export.js.map +7 -0
  23. package/dist/commands/mcp-interactive.js +21 -12
  24. package/dist/commands/mcp-interactive.js.map +2 -2
  25. package/dist/commands/model.js +6 -5
  26. package/dist/commands/model.js.map +2 -2
  27. package/dist/commands/permissions.js +86 -0
  28. package/dist/commands/permissions.js.map +7 -0
  29. package/dist/commands/quit.js +3 -1
  30. package/dist/commands/quit.js.map +2 -2
  31. package/dist/commands/sandbox.js +104 -0
  32. package/dist/commands/sandbox.js.map +7 -0
  33. package/dist/commands/status.js +58 -0
  34. package/dist/commands/status.js.map +7 -0
  35. package/dist/commands/tasks.js +108 -0
  36. package/dist/commands/tasks.js.map +7 -0
  37. package/dist/commands/todos.js +123 -0
  38. package/dist/commands/todos.js.map +7 -0
  39. package/dist/commands.js +20 -2
  40. package/dist/commands.js.map +2 -2
  41. package/dist/components/AgentThinkingBlock.js +10 -18
  42. package/dist/components/AgentThinkingBlock.js.map +2 -2
  43. package/dist/components/BackgroundTasksPanel.js +78 -29
  44. package/dist/components/BackgroundTasksPanel.js.map +2 -2
  45. package/dist/components/BashStreamingProgress.js +24 -0
  46. package/dist/components/BashStreamingProgress.js.map +7 -0
  47. package/dist/components/CollapsibleHint.js +14 -0
  48. package/dist/components/CollapsibleHint.js.map +7 -0
  49. package/dist/components/FileEditToolUpdatedMessage.js +1 -1
  50. package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
  51. package/dist/components/HotkeyHelpPanel.js +137 -0
  52. package/dist/components/HotkeyHelpPanel.js.map +7 -0
  53. package/dist/components/Logo.js +5 -5
  54. package/dist/components/Logo.js.map +2 -2
  55. package/dist/components/Message.js +23 -7
  56. package/dist/components/Message.js.map +3 -3
  57. package/dist/components/ModelConfig.js +16 -3
  58. package/dist/components/ModelConfig.js.map +2 -2
  59. package/dist/components/ModelListManager.js +3 -3
  60. package/dist/components/ModelListManager.js.map +2 -2
  61. package/dist/components/ModelSelector/ModelSelector.js +1 -1
  62. package/dist/components/Onboarding.js +19 -14
  63. package/dist/components/Onboarding.js.map +2 -2
  64. package/dist/components/ProgressBar.js +74 -0
  65. package/dist/components/ProgressBar.js.map +7 -0
  66. package/dist/components/PromptInput.js +156 -46
  67. package/dist/components/PromptInput.js.map +2 -2
  68. package/dist/components/RequestStatusIndicator.js +194 -0
  69. package/dist/components/RequestStatusIndicator.js.map +7 -0
  70. package/dist/components/Spinner.js +92 -27
  71. package/dist/components/Spinner.js.map +2 -2
  72. package/dist/components/SpinnerSymbol.js +21 -27
  73. package/dist/components/SpinnerSymbol.js.map +2 -2
  74. package/dist/components/StreamingBashOutput.js +9 -8
  75. package/dist/components/StreamingBashOutput.js.map +2 -2
  76. package/dist/components/SubagentBlock.js +1 -1
  77. package/dist/components/SubagentBlock.js.map +1 -1
  78. package/dist/components/SubagentProgress.js +10 -11
  79. package/dist/components/SubagentProgress.js.map +2 -2
  80. package/dist/components/TaskCard.js +16 -13
  81. package/dist/components/TaskCard.js.map +2 -2
  82. package/dist/components/TodoChangeBlock.js +1 -1
  83. package/dist/components/TodoChangeBlock.js.map +2 -2
  84. package/dist/components/TodoPanel.js +120 -29
  85. package/dist/components/TodoPanel.js.map +3 -3
  86. package/dist/components/TokenCounter.js +74 -0
  87. package/dist/components/TokenCounter.js.map +7 -0
  88. package/dist/components/TokenWarning.js +2 -1
  89. package/dist/components/TokenWarning.js.map +2 -2
  90. package/dist/components/TreeConnector.js +25 -0
  91. package/dist/components/TreeConnector.js.map +7 -0
  92. package/dist/components/TurnCompletionIndicator.js +18 -0
  93. package/dist/components/TurnCompletionIndicator.js.map +7 -0
  94. package/dist/components/messages/AssistantTextMessage.js +5 -2
  95. package/dist/components/messages/AssistantTextMessage.js.map +2 -2
  96. package/dist/components/messages/AssistantThinkingMessage.js +18 -3
  97. package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
  98. package/dist/components/messages/AssistantToolUseMessage.js +11 -8
  99. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  100. package/dist/components/messages/GroupRenderer.js +53 -0
  101. package/dist/components/messages/GroupRenderer.js.map +7 -0
  102. package/dist/components/messages/NestedTasksPreview.js +12 -0
  103. package/dist/components/messages/NestedTasksPreview.js.map +7 -0
  104. package/dist/components/messages/ParallelTasksGroupView.js +92 -0
  105. package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
  106. package/dist/components/messages/TaskInModuleView.js +198 -0
  107. package/dist/components/messages/TaskInModuleView.js.map +7 -0
  108. package/dist/components/messages/TaskOutputContent.js +53 -0
  109. package/dist/components/messages/TaskOutputContent.js.map +7 -0
  110. package/dist/components/messages/UserPromptMessage.js +1 -1
  111. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  112. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
  113. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
  114. package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
  115. package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
  116. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
  117. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
  118. package/dist/constants/colors.js +48 -0
  119. package/dist/constants/colors.js.map +2 -2
  120. package/dist/constants/formatRules.js +102 -0
  121. package/dist/constants/formatRules.js.map +7 -0
  122. package/dist/constants/prompts.js +12 -34
  123. package/dist/constants/prompts.js.map +2 -2
  124. package/dist/constants/symbols.js +64 -6
  125. package/dist/constants/symbols.js.map +2 -2
  126. package/dist/constants/timing.js +5 -0
  127. package/dist/constants/timing.js.map +2 -2
  128. package/dist/core/config/defaults.js +84 -0
  129. package/dist/core/config/defaults.js.map +7 -0
  130. package/dist/core/config/index.js +111 -0
  131. package/dist/core/config/index.js.map +7 -0
  132. package/dist/core/config/loader.js +221 -0
  133. package/dist/core/config/loader.js.map +7 -0
  134. package/dist/core/config/migrations.js +128 -0
  135. package/dist/core/config/migrations.js.map +7 -0
  136. package/dist/core/config/schema.js +178 -0
  137. package/dist/core/config/schema.js.map +7 -0
  138. package/dist/core/costTracker.js +138 -0
  139. package/dist/core/costTracker.js.map +7 -0
  140. package/dist/core/index.js +5 -0
  141. package/dist/core/index.js.map +7 -0
  142. package/dist/core/permissions/auditLog.js +204 -0
  143. package/dist/core/permissions/auditLog.js.map +7 -0
  144. package/dist/core/permissions/engine/index.js +3 -0
  145. package/dist/core/permissions/engine/index.js.map +7 -0
  146. package/dist/core/permissions/engine/permissionEngine.js +106 -0
  147. package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
  148. package/dist/core/permissions/engine/types.js +1 -0
  149. package/dist/core/permissions/engine/types.js.map +7 -0
  150. package/dist/core/permissions/index.js +84 -0
  151. package/dist/core/permissions/index.js.map +7 -0
  152. package/dist/core/permissions/ruleEngine.js +259 -0
  153. package/dist/core/permissions/ruleEngine.js.map +7 -0
  154. package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
  155. package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
  156. package/dist/core/permissions/rules/autoEscalationRule.js +291 -0
  157. package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
  158. package/dist/core/permissions/rules/index.js +46 -0
  159. package/dist/core/permissions/rules/index.js.map +7 -0
  160. package/dist/core/permissions/rules/planModeRule.js +55 -0
  161. package/dist/core/permissions/rules/planModeRule.js.map +7 -0
  162. package/dist/core/permissions/rules/projectBoundaryRule.js +168 -0
  163. package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
  164. package/dist/core/permissions/rules/safeModeRule.js +65 -0
  165. package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
  166. package/dist/core/permissions/rules/sensitivePathsRule.js +340 -0
  167. package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
  168. package/dist/core/permissions/types.js +127 -0
  169. package/dist/core/permissions/types.js.map +7 -0
  170. package/dist/core/tools/executor.js +143 -0
  171. package/dist/core/tools/executor.js.map +7 -0
  172. package/dist/core/tools/index.js +15 -0
  173. package/dist/core/tools/index.js.map +7 -0
  174. package/dist/core/tools/registry.js +183 -0
  175. package/dist/core/tools/registry.js.map +7 -0
  176. package/dist/core/tools/types.js +1 -0
  177. package/dist/core/tools/types.js.map +7 -0
  178. package/dist/cost-tracker.js +23 -15
  179. package/dist/cost-tracker.js.map +2 -2
  180. package/dist/entrypoints/cli.js +43 -43
  181. package/dist/entrypoints/cli.js.map +2 -2
  182. package/dist/entrypoints/mcp.js +12 -4
  183. package/dist/entrypoints/mcp.js.map +2 -2
  184. package/dist/history.js +14 -3
  185. package/dist/history.js.map +2 -2
  186. package/dist/hooks/useAgentTranscripts.js +116 -0
  187. package/dist/hooks/useAgentTranscripts.js.map +7 -0
  188. package/dist/hooks/useAnimationSync.js +53 -0
  189. package/dist/hooks/useAnimationSync.js.map +7 -0
  190. package/dist/hooks/useArrowKeyHistory.js +4 -2
  191. package/dist/hooks/useArrowKeyHistory.js.map +2 -2
  192. package/dist/hooks/useCanUseTool.js +3 -1
  193. package/dist/hooks/useCanUseTool.js.map +2 -2
  194. package/dist/hooks/useCancelRequest.js +4 -1
  195. package/dist/hooks/useCancelRequest.js.map +2 -2
  196. package/dist/hooks/useExitOnCtrlCD.js +9 -5
  197. package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
  198. package/dist/hooks/useHookStatus.js +40 -0
  199. package/dist/hooks/useHookStatus.js.map +7 -0
  200. package/dist/hooks/useLogMessages.js +17 -1
  201. package/dist/hooks/useLogMessages.js.map +2 -2
  202. package/dist/hooks/useMessageGroups.js +43 -0
  203. package/dist/hooks/useMessageGroups.js.map +7 -0
  204. package/dist/hooks/useTerminalSize.js +62 -6
  205. package/dist/hooks/useTerminalSize.js.map +2 -2
  206. package/dist/hooks/useUnifiedCompletion.js +69 -0
  207. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  208. package/dist/i18n/index.js +109 -0
  209. package/dist/i18n/index.js.map +7 -0
  210. package/dist/i18n/locales/en.js +347 -0
  211. package/dist/i18n/locales/en.js.map +7 -0
  212. package/dist/i18n/locales/index.js +7 -0
  213. package/dist/i18n/locales/index.js.map +7 -0
  214. package/dist/i18n/locales/zh-CN.js +347 -0
  215. package/dist/i18n/locales/zh-CN.js.map +7 -0
  216. package/dist/i18n/types.js +8 -0
  217. package/dist/i18n/types.js.map +7 -0
  218. package/dist/query.js +175 -17
  219. package/dist/query.js.map +3 -3
  220. package/dist/screens/REPL.js +501 -192
  221. package/dist/screens/REPL.js.map +3 -3
  222. package/dist/services/adapters/chatCompletions.js +3 -1
  223. package/dist/services/adapters/chatCompletions.js.map +2 -2
  224. package/dist/services/adapters/messageNormalizer.js +354 -0
  225. package/dist/services/adapters/messageNormalizer.js.map +7 -0
  226. package/dist/services/adapters/responsesAPI.js +6 -3
  227. package/dist/services/adapters/responsesAPI.js.map +2 -2
  228. package/dist/services/checkpointManager.js +386 -0
  229. package/dist/services/checkpointManager.js.map +7 -0
  230. package/dist/services/claude.js +138 -11
  231. package/dist/services/claude.js.map +3 -3
  232. package/dist/services/compressionService.js +50 -1
  233. package/dist/services/compressionService.js.map +2 -2
  234. package/dist/services/contextMonitor.js +162 -0
  235. package/dist/services/contextMonitor.js.map +7 -0
  236. package/dist/services/customCommands.js +60 -41
  237. package/dist/services/customCommands.js.map +2 -2
  238. package/dist/services/hookExecutor.js +173 -1
  239. package/dist/services/hookExecutor.js.map +2 -2
  240. package/dist/services/intelligentCompactor.js +281 -0
  241. package/dist/services/intelligentCompactor.js.map +7 -0
  242. package/dist/services/lspConfig.js +109 -0
  243. package/dist/services/lspConfig.js.map +7 -0
  244. package/dist/services/mcpClient.js +273 -34
  245. package/dist/services/mcpClient.js.map +2 -2
  246. package/dist/services/modelOrchestrator.js +310 -0
  247. package/dist/services/modelOrchestrator.js.map +7 -0
  248. package/dist/services/openai.js +8 -1
  249. package/dist/services/openai.js.map +2 -2
  250. package/dist/services/outputStyles.js +138 -0
  251. package/dist/services/outputStyles.js.map +7 -0
  252. package/dist/services/plugins/index.js +5 -0
  253. package/dist/services/plugins/index.js.map +7 -0
  254. package/dist/services/plugins/lspServers.js +188 -0
  255. package/dist/services/plugins/lspServers.js.map +7 -0
  256. package/dist/services/plugins/pluginRuntime.js +229 -0
  257. package/dist/services/plugins/pluginRuntime.js.map +7 -0
  258. package/dist/services/plugins/pluginValidation.js +219 -0
  259. package/dist/services/plugins/pluginValidation.js.map +7 -0
  260. package/dist/services/plugins/skillMarketplace.js +556 -0
  261. package/dist/services/plugins/skillMarketplace.js.map +7 -0
  262. package/dist/services/responseStateManager.js +37 -3
  263. package/dist/services/responseStateManager.js.map +2 -2
  264. package/dist/services/sandbox/filesystemBoundary.js +300 -0
  265. package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
  266. package/dist/services/sandbox/index.js +14 -0
  267. package/dist/services/sandbox/index.js.map +7 -0
  268. package/dist/services/sandbox/networkProxy.js +293 -0
  269. package/dist/services/sandbox/networkProxy.js.map +7 -0
  270. package/dist/services/sandbox/sandboxController.js +574 -0
  271. package/dist/services/sandbox/sandboxController.js.map +7 -0
  272. package/dist/services/sandbox/types.js +50 -0
  273. package/dist/services/sandbox/types.js.map +7 -0
  274. package/dist/services/sessionMemory.js +266 -0
  275. package/dist/services/sessionMemory.js.map +7 -0
  276. package/dist/services/taskRouter.js +324 -0
  277. package/dist/services/taskRouter.js.map +7 -0
  278. package/dist/tools/ArchitectTool/ArchitectTool.js +7 -1
  279. package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
  280. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -0
  281. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  282. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
  283. package/dist/tools/BaseTool.js +72 -0
  284. package/dist/tools/BaseTool.js.map +7 -0
  285. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
  286. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
  287. package/dist/tools/BashTool/BashTool.js +60 -3
  288. package/dist/tools/BashTool/BashTool.js.map +2 -2
  289. package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
  290. package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
  291. package/dist/tools/BashTool/OutputLine.js +54 -0
  292. package/dist/tools/BashTool/OutputLine.js.map +2 -2
  293. package/dist/tools/BashTool/prompt.js +192 -3
  294. package/dist/tools/BashTool/prompt.js.map +2 -2
  295. package/dist/tools/FileEditTool/FileEditTool.js +29 -4
  296. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  297. package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
  298. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  299. package/dist/tools/GlobTool/GlobTool.js +4 -2
  300. package/dist/tools/GlobTool/GlobTool.js.map +2 -2
  301. package/dist/tools/GrepTool/GrepTool.js +36 -7
  302. package/dist/tools/GrepTool/GrepTool.js.map +2 -2
  303. package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
  304. package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
  305. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
  306. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
  307. package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
  308. package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
  309. package/dist/tools/LspTool/LspTool.js +664 -0
  310. package/dist/tools/LspTool/LspTool.js.map +7 -0
  311. package/dist/tools/LspTool/prompt.js +27 -0
  312. package/dist/tools/LspTool/prompt.js.map +7 -0
  313. package/dist/tools/MCPTool/MCPTool.js +9 -1
  314. package/dist/tools/MCPTool/MCPTool.js.map +2 -2
  315. package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
  316. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  317. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
  318. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  319. package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
  320. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  321. package/dist/tools/NotebookEditTool/NotebookEditTool.js +5 -1
  322. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  323. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
  324. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +74 -0
  325. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
  326. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +108 -0
  327. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
  328. package/dist/tools/PlanModeTool/prompt.js +94 -0
  329. package/dist/tools/PlanModeTool/prompt.js.map +7 -0
  330. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
  331. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
  332. package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
  333. package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
  334. package/dist/tools/SkillTool/SkillTool.js +6 -1
  335. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  336. package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
  337. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
  338. package/dist/tools/SlashCommandTool/prompt.js +35 -0
  339. package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
  340. package/dist/tools/TaskOutputTool/TaskOutputTool.js +189 -0
  341. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
  342. package/dist/tools/TaskOutputTool/prompt.js +15 -0
  343. package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
  344. package/dist/tools/TaskTool/TaskTool.js +302 -104
  345. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  346. package/dist/tools/TaskTool/prompt.js.map +2 -2
  347. package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -77
  348. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
  349. package/dist/tools/URLFetcherTool/URLFetcherTool.js +4 -1
  350. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
  351. package/dist/tools/URLFetcherTool/cache.js +55 -8
  352. package/dist/tools/URLFetcherTool/cache.js.map +2 -2
  353. package/dist/tools.js +31 -2
  354. package/dist/tools.js.map +2 -2
  355. package/dist/types/hooks.js +4 -0
  356. package/dist/types/hooks.js.map +2 -2
  357. package/dist/types/marketplace.js.map +2 -2
  358. package/dist/types/messageGroup.js +36 -0
  359. package/dist/types/messageGroup.js.map +7 -0
  360. package/dist/types/plugin.js.map +2 -2
  361. package/dist/types/thinking.js +1 -0
  362. package/dist/types/thinking.js.map +7 -0
  363. package/dist/utils/BackgroundShellManager.js +136 -39
  364. package/dist/utils/BackgroundShellManager.js.map +2 -2
  365. package/dist/utils/MessageBatchBuffer.js +102 -0
  366. package/dist/utils/MessageBatchBuffer.js.map +7 -0
  367. package/dist/utils/PersistentShell.js +151 -1
  368. package/dist/utils/PersistentShell.js.map +2 -2
  369. package/dist/utils/agentLoader.js +1 -23
  370. package/dist/utils/agentLoader.js.map +2 -2
  371. package/dist/utils/agentTranscripts.js +641 -0
  372. package/dist/utils/agentTranscripts.js.map +7 -0
  373. package/dist/utils/animationManager.js +213 -0
  374. package/dist/utils/animationManager.js.map +7 -0
  375. package/dist/utils/animationSync.js +110 -0
  376. package/dist/utils/animationSync.js.map +7 -0
  377. package/dist/utils/asyncFile.js +215 -0
  378. package/dist/utils/asyncFile.js.map +7 -0
  379. package/dist/utils/backgroundAgentManager.js +231 -0
  380. package/dist/utils/backgroundAgentManager.js.map +7 -0
  381. package/dist/utils/config.js +63 -7
  382. package/dist/utils/config.js.map +2 -2
  383. package/dist/utils/conversationRecovery.js +19 -0
  384. package/dist/utils/conversationRecovery.js.map +2 -2
  385. package/dist/utils/exit.js +73 -0
  386. package/dist/utils/exit.js.map +7 -0
  387. package/dist/utils/format.js +73 -5
  388. package/dist/utils/format.js.map +2 -2
  389. package/dist/utils/generators.js +76 -6
  390. package/dist/utils/generators.js.map +2 -2
  391. package/dist/utils/globalErrorHandler.js +149 -0
  392. package/dist/utils/globalErrorHandler.js.map +7 -0
  393. package/dist/utils/groupHandlers/index.js +8 -0
  394. package/dist/utils/groupHandlers/index.js.map +7 -0
  395. package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
  396. package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
  397. package/dist/utils/groupHandlers/taskHandler.js +104 -0
  398. package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
  399. package/dist/utils/groupHandlers/types.js +1 -0
  400. package/dist/utils/groupHandlers/types.js.map +7 -0
  401. package/dist/utils/logRotation.js +224 -0
  402. package/dist/utils/logRotation.js.map +7 -0
  403. package/dist/utils/marketplaceManager.js +3 -5
  404. package/dist/utils/marketplaceManager.js.map +2 -2
  405. package/dist/utils/memSafety.js +264 -0
  406. package/dist/utils/memSafety.js.map +7 -0
  407. package/dist/utils/messageGroupManager.js +274 -0
  408. package/dist/utils/messageGroupManager.js.map +7 -0
  409. package/dist/utils/messages.js +13 -4
  410. package/dist/utils/messages.js.map +2 -2
  411. package/dist/utils/model.js +119 -15
  412. package/dist/utils/model.js.map +3 -3
  413. package/dist/utils/permissions/filesystem.js +157 -5
  414. package/dist/utils/permissions/filesystem.js.map +2 -2
  415. package/dist/utils/plan/planMode.js +143 -0
  416. package/dist/utils/plan/planMode.js.map +7 -0
  417. package/dist/utils/pluginLoader.js +17 -21
  418. package/dist/utils/pluginLoader.js.map +2 -2
  419. package/dist/utils/ripgrep.js +55 -2
  420. package/dist/utils/ripgrep.js.map +2 -2
  421. package/dist/utils/sanitizeInput.js +32 -0
  422. package/dist/utils/sanitizeInput.js.map +7 -0
  423. package/dist/utils/secureKeyStorage.js +312 -0
  424. package/dist/utils/secureKeyStorage.js.map +7 -0
  425. package/dist/utils/session/sessionPlugins.js +67 -0
  426. package/dist/utils/session/sessionPlugins.js.map +7 -0
  427. package/dist/utils/taskDisplayUtils.js +257 -0
  428. package/dist/utils/taskDisplayUtils.js.map +7 -0
  429. package/dist/utils/teamConfig.js +2 -1
  430. package/dist/utils/teamConfig.js.map +2 -2
  431. package/dist/utils/todoStorage.js +92 -2
  432. package/dist/utils/todoStorage.js.map +2 -2
  433. package/dist/utils/toolTimeout.js +136 -0
  434. package/dist/utils/toolTimeout.js.map +7 -0
  435. package/dist/utils/tooling/safeRender.js +115 -0
  436. package/dist/utils/tooling/safeRender.js.map +7 -0
  437. package/dist/utils/userFriendlyError.js +346 -0
  438. package/dist/utils/userFriendlyError.js.map +7 -0
  439. package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
  440. package/dist/version.js +2 -2
  441. package/dist/version.js.map +1 -1
  442. package/package.json +14 -4
  443. package/scripts/postinstall.js +128 -38
  444. package/dist/commands/agents.js +0 -2086
  445. package/dist/commands/agents.js.map +0 -7
  446. package/dist/commands/build.js +0 -74
  447. package/dist/commands/build.js.map +0 -7
  448. package/dist/commands/compression.js +0 -57
  449. package/dist/commands/compression.js.map +0 -7
  450. package/dist/commands/listen.js +0 -37
  451. package/dist/commands/listen.js.map +0 -7
  452. package/dist/commands/login.js +0 -37
  453. package/dist/commands/login.js.map +0 -7
  454. package/dist/commands/logout.js +0 -33
  455. package/dist/commands/logout.js.map +0 -7
  456. package/dist/commands/mcp.js +0 -40
  457. package/dist/commands/mcp.js.map +0 -7
  458. package/dist/commands/mcp_refresh.js +0 -40
  459. package/dist/commands/mcp_refresh.js.map +0 -7
  460. package/dist/commands/modelstatus.js +0 -21
  461. package/dist/commands/modelstatus.js.map +0 -7
  462. package/dist/commands/onboarding.js +0 -36
  463. package/dist/commands/onboarding.js.map +0 -7
  464. package/dist/commands/plugin-interactive.js +0 -446
  465. package/dist/commands/plugin-interactive.js.map +0 -7
  466. package/dist/commands/pr_comments.js +0 -61
  467. package/dist/commands/pr_comments.js.map +0 -7
  468. package/dist/commands/release-notes.js +0 -30
  469. package/dist/commands/release-notes.js.map +0 -7
  470. package/dist/commands/review.js +0 -51
  471. package/dist/commands/review.js.map +0 -7
  472. package/dist/components/Bug.js +0 -147
  473. package/dist/components/Bug.js.map +0 -7
  474. package/dist/components/ModelSelector.js +0 -2062
  475. package/dist/components/ModelSelector.js.map +0 -7
  476. package/dist/components/ModelStatusDisplay.js +0 -87
  477. package/dist/components/ModelStatusDisplay.js.map +0 -7
  478. package/dist/entrypoints/cli-wrapper.js +0 -61
  479. package/dist/entrypoints/cli-wrapper.js.map +0 -7
  480. package/dist/screens/Doctor.js +0 -22
  481. package/dist/screens/Doctor.js.map +0 -7
@@ -8,25 +8,27 @@ import { useEffect, useMemo, useRef, useState, useCallback } from "react";
8
8
  import { Logo } from "../components/Logo.js";
9
9
  import { Message } from "../components/Message.js";
10
10
  import { MessageResponse } from "../components/MessageResponse.js";
11
+ import { BashStreamingProgress } from "../components/BashStreamingProgress.js";
11
12
  import { MessageSelector } from "../components/MessageSelector.js";
13
+ import { MessageBatchBuffer } from "../utils/MessageBatchBuffer.js";
12
14
  import {
13
15
  PermissionRequest
14
16
  } from "../components/permissions/PermissionRequest.js";
15
17
  import PromptInput from "../components/PromptInput.js";
16
- import { Spinner } from "../components/Spinner.js";
17
18
  import { getSystemPrompt } from "../constants/prompts.js";
18
19
  import { getContext } from "../context.js";
19
20
  import { getTotalCost, useCostSummary } from "../cost-tracker.js";
20
21
  import { useLogStartupTime } from "../hooks/useLogStartupTime.js";
21
22
  import { addToHistory } from "../history.js";
22
23
  import { useApiKeyVerification } from "../hooks/useApiKeyVerification.js";
23
- import { useCancelRequest } from "../hooks/useCancelRequest.js";
24
24
  import useCanUseTool from "../hooks/useCanUseTool.js";
25
25
  import { useLogMessages } from "../hooks/useLogMessages.js";
26
26
  import { PermissionProvider } from "../context/PermissionContext.js";
27
+ import { useFullscreenExitCallback } from "../hooks/useTerminalSize.js";
27
28
  import { ModeIndicator } from "../components/ModeIndicator.js";
28
29
  import { TodoPanel } from "../components/TodoPanel.js";
29
- import { getTodos } from "../utils/todoStorage.js";
30
+ import { TurnCompletionIndicator } from "../components/TurnCompletionIndicator.js";
31
+ import { getTodos, initTodoSession } from "../utils/todoStorage.js";
30
32
  import {
31
33
  setMessagesGetter,
32
34
  setMessagesSetter,
@@ -35,7 +37,11 @@ import {
35
37
  import {
36
38
  query
37
39
  } from "../query.js";
38
- import { getGlobalConfig, saveGlobalConfig } from "../utils/config.js";
40
+ import {
41
+ getGlobalConfig,
42
+ saveGlobalConfig,
43
+ getVerboseLabel
44
+ } from "../utils/config.js";
39
45
  import { getNextAvailableLogForkNumber } from "../utils/log.js";
40
46
  import {
41
47
  getErroredToolUseMessages,
@@ -48,8 +54,10 @@ import {
48
54
  normalizeMessages,
49
55
  normalizeMessagesForAPI,
50
56
  processUserInput,
51
- reorderMessages
57
+ reorderMessages,
58
+ createAssistantAPIErrorMessage
52
59
  } from "../utils/messages.js";
60
+ import { logError } from "../utils/log.js";
53
61
  import { ModelManager } from "../utils/model.js";
54
62
  import { clearTerminal } from "../utils/terminal.js";
55
63
  import { BinaryFeedback } from "../components/binary-feedback/BinaryFeedback.js";
@@ -68,7 +76,14 @@ import {
68
76
  } from "../utils/BackgroundShellManager.js";
69
77
  import { BackgroundTasksPanel } from "../components/BackgroundTasksPanel.js";
70
78
  import { AskUserQuestionDialog } from "../components/AskUserQuestionDialog/AskUserQuestionDialog.js";
79
+ import {
80
+ getToolUseIdByAgentId,
81
+ restoreToolUseAgentMappings
82
+ } from "../utils/agentTranscripts.js";
71
83
  import useAskUser from "../hooks/useAskUser.js";
84
+ import { useMessageGroups } from "../hooks/useMessageGroups.js";
85
+ import { useAgentTranscripts } from "../hooks/useAgentTranscripts.js";
86
+ import { GroupRenderer } from "../components/messages/GroupRenderer.js";
72
87
  const RESUME_VISIBLE_MESSAGE_COUNT = 10;
73
88
  function REPL({
74
89
  commands,
@@ -89,11 +104,19 @@ function REPL({
89
104
  isResumedConversation = false
90
105
  }) {
91
106
  const [verbose, setVerbose] = useState(
92
- () => verboseFromCLI ?? getGlobalConfig().verbose
107
+ verboseFromCLI === true ? true : false
93
108
  );
94
109
  const [forkNumber, setForkNumber] = useState(
95
110
  getNextAvailableLogForkNumber(messageLogName, initialForkNumber, 0)
96
111
  );
112
+ const [isResizeClearing, setIsResizeClearing] = useState(false);
113
+ useFullscreenExitCallback(async () => {
114
+ setIsResizeClearing(true);
115
+ await new Promise((resolve) => setTimeout(resolve, 50));
116
+ await clearTerminal();
117
+ setForkNumber((prev) => prev + 1);
118
+ setIsResizeClearing(false);
119
+ });
97
120
  const [
98
121
  forkConvoWithMessagesOnTheNextRender,
99
122
  setForkConvoWithMessagesOnTheNextRender
@@ -121,11 +144,52 @@ function REPL({
121
144
  const updateAvailableVersion = initialUpdateVersion ?? null;
122
145
  const updateCommands = initialUpdateCommands ?? null;
123
146
  const [isTodoPanelVisible, setIsTodoPanelVisible] = useState(true);
124
- const [startTime] = useState(Date.now());
147
+ const [verboseToggleMessage, setVerboseToggleMessage] = useState(null);
148
+ const turnStartTimeRef = useRef(null);
149
+ const [lastTurnDurationMs, setLastTurnDurationMs] = useState(
150
+ null
151
+ );
152
+ const [queuedPrompts, setQueuedPrompts] = useState([]);
153
+ const queuedPromptsRef = useRef([]);
154
+ useEffect(() => {
155
+ queuedPromptsRef.current = queuedPrompts;
156
+ }, [queuedPrompts]);
157
+ useEffect(() => {
158
+ if (isLoading) {
159
+ turnStartTimeRef.current = Date.now();
160
+ setLastTurnDurationMs(null);
161
+ } else if (turnStartTimeRef.current !== null) {
162
+ const duration = Date.now() - turnStartTimeRef.current;
163
+ setLastTurnDurationMs(duration);
164
+ turnStartTimeRef.current = null;
165
+ }
166
+ }, [isLoading]);
125
167
  const [backgroundShells, setBackgroundShells] = useState(
126
168
  []
127
169
  );
128
170
  const [showBackgroundPanel, setShowBackgroundPanel] = useState(false);
171
+ const prevUnresolvedRef = useRef(/* @__PURE__ */ new Set());
172
+ const messageBatchBufferRef = useRef(null);
173
+ if (messageBatchBufferRef.current === null) {
174
+ messageBatchBufferRef.current = new MessageBatchBuffer(
175
+ (batchedMessages) => {
176
+ setMessages((prev) => [...prev, ...batchedMessages]);
177
+ },
178
+ {
179
+ flushInterval: 100,
180
+ // Batch messages for 100ms
181
+ maxBatchSize: 50,
182
+ // Force flush if 50+ messages buffered
183
+ debug: false
184
+ // Set to true for debugging
185
+ }
186
+ );
187
+ }
188
+ useEffect(() => {
189
+ return () => {
190
+ messageBatchBufferRef.current?.dispose();
191
+ };
192
+ }, []);
129
193
  const getBinaryFeedbackResponse = useCallback(
130
194
  (m1, m2) => {
131
195
  return new Promise((resolvePromise) => {
@@ -141,10 +205,13 @@ function REPL({
141
205
  const readFileTimestamps = useRef({});
142
206
  const hookManagerRef = useRef(null);
143
207
  const { status: apiKeyStatus, reverify } = useApiKeyVerification();
144
- function onCancel() {
208
+ function onInterrupt() {
145
209
  if (!isLoading) {
146
210
  return;
147
211
  }
212
+ setToolJSX(null);
213
+ setToolUseConfirm(null);
214
+ setBinaryFeedbackContext(null);
148
215
  setIsLoading(false);
149
216
  if (toolUseConfirm) {
150
217
  toolUseConfirm.onAbort();
@@ -152,15 +219,9 @@ function REPL({
152
219
  abortController.abort();
153
220
  }
154
221
  }
155
- useCancelRequest(
156
- setToolJSX,
157
- setToolUseConfirm,
158
- setBinaryFeedbackContext,
159
- onCancel,
160
- isLoading,
161
- isMessageSelectorVisible,
162
- abortController?.signal
163
- );
222
+ function onCancel() {
223
+ onInterrupt();
224
+ }
164
225
  useEffect(() => {
165
226
  if (forkConvoWithMessagesOnTheNextRender) {
166
227
  setForkNumber((_) => _ + 1);
@@ -184,79 +245,89 @@ function REPL({
184
245
  setIsLoading(true);
185
246
  const newAbortController = new AbortController();
186
247
  setAbortController(newAbortController);
187
- const model = new ModelManager(getGlobalConfig()).getModelName("main");
188
- const newMessages = await processUserInput(
189
- initialPrompt,
190
- "prompt",
191
- setToolJSX,
192
- {
193
- abortController: newAbortController,
194
- options: {
195
- commands,
196
- forkNumber,
197
- messageLogName,
198
- tools,
199
- verbose,
200
- maxThinkingTokens: 0
201
- },
202
- messageId: getLastAssistantMessageId(messages),
203
- setForkConvoWithMessagesOnTheNextRender,
204
- readFileTimestamps: readFileTimestamps.current
205
- },
206
- null
207
- );
208
- if (newMessages.length) {
209
- for (const message of newMessages) {
210
- if (message.type === "user") {
211
- addToHistory(initialPrompt);
212
- }
213
- }
214
- setMessages((_) => [..._, ...newMessages]);
215
- const lastMessage = newMessages[newMessages.length - 1];
216
- if (lastMessage.type === "assistant") {
217
- setAbortController(null);
218
- setIsLoading(false);
219
- return;
220
- }
221
- const [systemPrompt, context, model2, maxThinkingTokens] = await Promise.all([
222
- getSystemPrompt(),
223
- getContext(),
224
- new ModelManager(getGlobalConfig()).getModelName("main"),
225
- getMaxThinkingTokens([...messages, ...newMessages])
226
- ]);
227
- for await (const message of query(
228
- [...messages, ...newMessages],
229
- systemPrompt,
230
- context,
231
- canUseTool,
248
+ try {
249
+ const model = new ModelManager(getGlobalConfig()).getModelName("main");
250
+ const newMessages = await processUserInput(
251
+ initialPrompt,
252
+ "prompt",
253
+ setToolJSX,
232
254
  {
255
+ abortController: newAbortController,
233
256
  options: {
234
257
  commands,
235
258
  forkNumber,
236
259
  messageLogName,
237
260
  tools,
238
261
  verbose,
239
- safeMode,
240
- maxThinkingTokens
262
+ maxThinkingTokens: 0
241
263
  },
242
- messageId: getLastAssistantMessageId([...messages, ...newMessages]),
243
- readFileTimestamps: readFileTimestamps.current,
244
- abortController: newAbortController,
245
- setToolJSX,
246
- askUser
264
+ messageId: getLastAssistantMessageId(messages),
265
+ setForkConvoWithMessagesOnTheNextRender,
266
+ readFileTimestamps: readFileTimestamps.current
247
267
  },
248
- getBinaryFeedbackResponse
249
- )) {
250
- setMessages((oldMessages) => [...oldMessages, message]);
268
+ null
269
+ );
270
+ if (newMessages.length) {
271
+ for (const message of newMessages) {
272
+ if (message.type === "user") {
273
+ addToHistory(initialPrompt);
274
+ }
275
+ }
276
+ setMessages((_) => [..._, ...newMessages]);
277
+ const lastMessage = newMessages[newMessages.length - 1];
278
+ if (lastMessage.type === "assistant") {
279
+ return;
280
+ }
281
+ const [systemPrompt, context, model2, maxThinkingTokens] = await Promise.all([
282
+ getSystemPrompt(),
283
+ getContext(),
284
+ new ModelManager(getGlobalConfig()).getModelName("main"),
285
+ getMaxThinkingTokens([...messages, ...newMessages])
286
+ ]);
287
+ for await (const message of query(
288
+ [...messages, ...newMessages],
289
+ systemPrompt,
290
+ context,
291
+ canUseTool,
292
+ {
293
+ options: {
294
+ commands,
295
+ forkNumber,
296
+ messageLogName,
297
+ tools,
298
+ verbose,
299
+ safeMode,
300
+ maxThinkingTokens
301
+ },
302
+ messageId: getLastAssistantMessageId([...messages, ...newMessages]),
303
+ readFileTimestamps: readFileTimestamps.current,
304
+ abortController: newAbortController,
305
+ setToolJSX,
306
+ askUser
307
+ },
308
+ getBinaryFeedbackResponse
309
+ )) {
310
+ messageBatchBufferRef.current?.add(message);
311
+ }
312
+ messageBatchBufferRef.current?.flush();
313
+ } else {
314
+ addToHistory(initialPrompt);
251
315
  }
252
- } else {
253
- addToHistory(initialPrompt);
316
+ setHaveShownCostDialog(
317
+ getGlobalConfig().hasAcknowledgedCostThreshold || false
318
+ );
319
+ } catch (error) {
320
+ logError(error);
321
+ setMessages((oldMessages) => [
322
+ ...oldMessages,
323
+ createAssistantAPIErrorMessage(
324
+ `Request failed: ${error instanceof Error ? error.message : String(error)}`
325
+ )
326
+ ]);
327
+ } finally {
328
+ setIsLoading(false);
329
+ setAbortController(null);
254
330
  }
255
- setHaveShownCostDialog(
256
- getGlobalConfig().hasAcknowledgedCostThreshold || false
257
- );
258
- setIsLoading(false);
259
- setAbortController(null);
260
331
  }
261
332
  function rollbackConversation() {
262
333
  if (messageHistory.length === 0) {
@@ -267,11 +338,14 @@ function REPL({
267
338
  setMessageHistory((history) => history.slice(0, -1));
268
339
  return true;
269
340
  }
341
+ const processNextQueuedPromptRef = useRef(null);
270
342
  async function onQuery(newMessages, passedAbortController) {
271
343
  const controllerToUse = passedAbortController || new AbortController();
272
344
  if (!passedAbortController) {
273
345
  setAbortController(controllerToUse);
274
346
  }
347
+ setIsLoading(true);
348
+ setVerbose(false);
275
349
  const isKodingRequest = newMessages.length > 0 && newMessages[0].type === "user" && "options" in newMessages[0] && newMessages[0].options?.isKodingRequest === true;
276
350
  setMessages((oldMessages) => {
277
351
  setMessageHistory((history) => [...history, oldMessages].slice(-10));
@@ -286,56 +360,75 @@ function REPL({
286
360
  setIsLoading(false);
287
361
  return;
288
362
  }
289
- const [systemPrompt, context, model, maxThinkingTokens] = await Promise.all(
290
- [
363
+ try {
364
+ const [systemPrompt, context, model, maxThinkingTokens] = await Promise.all([
291
365
  getSystemPrompt(),
292
366
  getContext(),
293
367
  new ModelManager(getGlobalConfig()).getModelName("main"),
294
368
  getMaxThinkingTokens([...messages, lastMessage])
295
- ]
296
- );
297
- let lastAssistantMessage = null;
298
- for await (const message of query(
299
- [...messages, lastMessage],
300
- systemPrompt,
301
- context,
302
- canUseTool,
303
- {
304
- options: {
305
- commands,
306
- forkNumber,
307
- messageLogName,
308
- tools,
309
- verbose,
310
- safeMode,
311
- maxThinkingTokens,
312
- // If this came from Koding mode, pass that along
313
- isKodingRequest: isKodingRequest || void 0
369
+ ]);
370
+ let lastAssistantMessage = null;
371
+ for await (const message of query(
372
+ [...messages, lastMessage],
373
+ systemPrompt,
374
+ context,
375
+ canUseTool,
376
+ {
377
+ options: {
378
+ commands,
379
+ forkNumber,
380
+ messageLogName,
381
+ tools,
382
+ verbose,
383
+ safeMode,
384
+ maxThinkingTokens,
385
+ // If this came from Koding mode, pass that along
386
+ isKodingRequest: isKodingRequest || void 0
387
+ },
388
+ messageId: getLastAssistantMessageId([...messages, lastMessage]),
389
+ readFileTimestamps: readFileTimestamps.current,
390
+ abortController: controllerToUse,
391
+ setToolJSX,
392
+ askUser
314
393
  },
315
- messageId: getLastAssistantMessageId([...messages, lastMessage]),
316
- readFileTimestamps: readFileTimestamps.current,
317
- abortController: controllerToUse,
318
- setToolJSX,
319
- askUser
320
- },
321
- getBinaryFeedbackResponse
322
- )) {
323
- setMessages((oldMessages) => [...oldMessages, message]);
324
- if (message.type === "assistant") {
325
- lastAssistantMessage = message;
394
+ getBinaryFeedbackResponse
395
+ )) {
396
+ messageBatchBufferRef.current?.add(message);
397
+ if (message.type === "assistant") {
398
+ lastAssistantMessage = message;
399
+ }
326
400
  }
327
- }
328
- if (isKodingRequest && lastAssistantMessage && lastAssistantMessage.type === "assistant") {
329
- try {
330
- const content = typeof lastAssistantMessage.message.content === "string" ? lastAssistantMessage.message.content : lastAssistantMessage.message.content.filter((block) => block.type === "text").map((block) => block.type === "text" ? block.text : "").join("\n");
331
- if (content && content.trim().length > 0) {
332
- handleHashCommand(content);
401
+ if (isKodingRequest && lastAssistantMessage && lastAssistantMessage.type === "assistant") {
402
+ try {
403
+ const content = typeof lastAssistantMessage.message.content === "string" ? lastAssistantMessage.message.content : lastAssistantMessage.message.content.filter((block) => block.type === "text").map((block) => block.type === "text" ? block.text : "").join("\n");
404
+ if (content && content.trim().length > 0) {
405
+ handleHashCommand(content);
406
+ }
407
+ } catch (error) {
408
+ console.error("Error saving response to project docs:", error);
333
409
  }
334
- } catch (error) {
335
- console.error("Error saving response to project docs:", error);
410
+ }
411
+ messageBatchBufferRef.current?.flush();
412
+ } catch (error) {
413
+ logError(error);
414
+ messageBatchBufferRef.current?.flush();
415
+ setMessages((oldMessages) => [
416
+ ...oldMessages,
417
+ createAssistantAPIErrorMessage(
418
+ `Request failed: ${error instanceof Error ? error.message : String(error)}`
419
+ )
420
+ ]);
421
+ } finally {
422
+ setIsLoading(false);
423
+ setAbortController(null);
424
+ if (queuedPromptsRef.current.length > 0) {
425
+ setTimeout(() => {
426
+ if (processNextQueuedPromptRef.current) {
427
+ processNextQueuedPromptRef.current();
428
+ }
429
+ }, 100);
336
430
  }
337
431
  }
338
- setIsLoading(false);
339
432
  }
340
433
  useCostSummary();
341
434
  useEffect(() => {
@@ -343,6 +436,13 @@ function REPL({
343
436
  setMessagesGetter(getMessages);
344
437
  setMessagesSetter(setMessages);
345
438
  }, [messages]);
439
+ useEffect(() => {
440
+ const todoSessionId = `${messageLogName}-${forkNumber}`;
441
+ initTodoSession(todoSessionId);
442
+ if (initialMessages && initialMessages.length > 0) {
443
+ restoreToolUseAgentMappings();
444
+ }
445
+ }, [messageLogName, forkNumber, initialMessages]);
346
446
  useEffect(() => {
347
447
  setModelConfigChangeHandler(() => {
348
448
  setForkNumber((prev) => prev + 1);
@@ -395,6 +495,9 @@ function REPL({
395
495
  () => getUnresolvedToolUseIDs(normalizedMessages),
396
496
  [normalizedMessages]
397
497
  );
498
+ useEffect(() => {
499
+ prevUnresolvedRef.current = new Set(unresolvedToolUseIDs);
500
+ }, [unresolvedToolUseIDs]);
398
501
  const inProgressToolUseIDs = useMemo(
399
502
  () => getInProgressToolUseIDs(normalizedMessages),
400
503
  [normalizedMessages]
@@ -407,11 +510,37 @@ function REPL({
407
510
  ),
408
511
  [normalizedMessages]
409
512
  );
513
+ const {
514
+ groups: messageGroups,
515
+ getGroupForMessage,
516
+ getGroupForToolUse,
517
+ shouldGroupBeStatic,
518
+ displayConfig
519
+ } = useMessageGroups(
520
+ normalizedMessages,
521
+ unresolvedToolUseIDs,
522
+ inProgressToolUseIDs,
523
+ verbose
524
+ );
525
+ const { transcripts: agentTranscripts, getTranscript } = useAgentTranscripts();
526
+ const toolOutputs = useMemo(() => {
527
+ const outputs = /* @__PURE__ */ new Map();
528
+ for (const msg of normalizedMessages) {
529
+ if (msg.type === "user" && msg.message.role === "user") {
530
+ for (const block of msg.message.content) {
531
+ if (typeof block === "object" && block.type === "tool_result") {
532
+ outputs.set(block.tool_use_id, block);
533
+ }
534
+ }
535
+ }
536
+ }
537
+ return outputs;
538
+ }, [normalizedMessages]);
410
539
  const messagesJSX = useMemo(() => {
411
540
  const reorderedMessages = reorderMessages(normalizedMessages);
412
541
  const hiddenMessageCount = isResumedConversation && reorderedMessages.length > RESUME_VISIBLE_MESSAGE_COUNT ? reorderedMessages.length - RESUME_VISIBLE_MESSAGE_COUNT : 0;
413
542
  const visibleMessages = hiddenMessageCount > 0 ? reorderedMessages.slice(-RESUME_VISIBLE_MESSAGE_COUNT) : reorderedMessages;
414
- return [
543
+ const result = [
415
544
  {
416
545
  type: "static",
417
546
  jsx: /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", key: `logo${forkNumber}` }, /* @__PURE__ */ React.createElement(
@@ -423,17 +552,102 @@ function REPL({
423
552
  updateBannerCommands: updateCommands
424
553
  }
425
554
  ), /* @__PURE__ */ React.createElement(ProjectOnboarding, { workspaceDir: getOriginalCwd() }))
426
- },
427
- // Show collapsed history indicator when resuming with hidden messages
428
- ...hiddenMessageCount > 0 ? [
429
- {
430
- type: "static",
431
- jsx: /* @__PURE__ */ React.createElement(Box, { key: "collapsed-history", paddingLeft: 2, marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\xB7\xB7\xB7 ", hiddenMessageCount, " earlier messages hidden \xB7\xB7\xB7"))
555
+ }
556
+ ];
557
+ if (hiddenMessageCount > 0) {
558
+ result.push({
559
+ type: "static",
560
+ jsx: /* @__PURE__ */ React.createElement(Box, { key: "collapsed-history", paddingLeft: 2, marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\xB7\xB7\xB7 ", hiddenMessageCount, " earlier messages hidden \xB7\xB7\xB7"))
561
+ });
562
+ }
563
+ const renderedGroupIds = /* @__PURE__ */ new Set();
564
+ const groupToolUseIds = /* @__PURE__ */ new Set();
565
+ const taskOutputToolUseIdsToSkip = /* @__PURE__ */ new Set();
566
+ for (const _ of visibleMessages) {
567
+ const toolUseID = getToolUseID(_);
568
+ let group = getGroupForMessage(_.uuid);
569
+ if (!group && _.type === "progress") {
570
+ group = getGroupForToolUse(_.toolUseID);
571
+ }
572
+ if (group && (group.type === "parallel-tasks" || group.type === "task")) {
573
+ if (renderedGroupIds.has(group.id)) {
574
+ continue;
575
+ }
576
+ renderedGroupIds.add(group.id);
577
+ if (group.metadata.siblingToolUseIds) {
578
+ for (const id of group.metadata.siblingToolUseIds) {
579
+ groupToolUseIds.add(id);
580
+ }
581
+ }
582
+ if (group.metadata.toolUseId) {
583
+ groupToolUseIds.add(group.metadata.toolUseId);
432
584
  }
433
- ] : [],
434
- ...visibleMessages.map((_) => {
435
- const toolUseID = getToolUseID(_);
436
- const message = _.type === "progress" ? _.content.message.content[0]?.type === "text" && // TaskTool interrupts use Progress messages without extra ⎿
585
+ const isGroupStatic = shouldGroupBeStatic(group);
586
+ const groupType = isGroupStatic ? "static" : "transient";
587
+ const shouldAnimate = !toolJSX && !toolUseConfirm && !isMessageSelectorVisible && !isGroupStatic;
588
+ result.push({
589
+ type: groupType,
590
+ jsx: /* @__PURE__ */ React.createElement(Box, { key: `group-${group.id}`, width: "100%" }, /* @__PURE__ */ React.createElement(
591
+ GroupRenderer,
592
+ {
593
+ group,
594
+ context: {
595
+ depth: 0,
596
+ isLastChild: true,
597
+ displayConfig,
598
+ shouldAnimate,
599
+ getTranscript
600
+ },
601
+ messages: normalizedMessages,
602
+ transcripts: agentTranscripts,
603
+ outputs: toolOutputs
604
+ }
605
+ ))
606
+ });
607
+ continue;
608
+ }
609
+ if (_.type === "user" && _.message.role === "user") {
610
+ const content = _.message.content;
611
+ if (Array.isArray(content)) {
612
+ const toolResult = content.find(
613
+ (block) => typeof block === "object" && block.type === "tool_result"
614
+ );
615
+ if (toolResult && (groupToolUseIds.has(toolResult.tool_use_id) || taskOutputToolUseIdsToSkip.has(toolResult.tool_use_id))) {
616
+ continue;
617
+ }
618
+ }
619
+ }
620
+ if (_.type === "assistant") {
621
+ const content = _.message.content;
622
+ if (Array.isArray(content)) {
623
+ const taskOutputCall = content.find(
624
+ (block) => typeof block === "object" && block.type === "tool_use" && block.name === "TaskOutput"
625
+ );
626
+ if (taskOutputCall) {
627
+ const taskId = taskOutputCall.input?.task_id;
628
+ if (taskId) {
629
+ const correspondingToolUseId = getToolUseIdByAgentId(taskId);
630
+ if (correspondingToolUseId && groupToolUseIds.has(correspondingToolUseId)) {
631
+ taskOutputToolUseIdsToSkip.add(taskOutputCall.id);
632
+ continue;
633
+ }
634
+ }
635
+ }
636
+ }
637
+ }
638
+ if (_.type === "progress" && "type" in _.content && _.content.type === "streaming" && !unresolvedToolUseIDs.has(_.toolUseID)) {
639
+ continue;
640
+ }
641
+ const message = _.type === "progress" ? (
642
+ // Check if this is a streaming progress content (e.g., from BashTool)
643
+ "type" in _.content && _.content.type === "streaming" ? /* @__PURE__ */ React.createElement(
644
+ BashStreamingProgress,
645
+ {
646
+ stdout: _.content.stdout,
647
+ stderr: _.content.stderr,
648
+ isStreaming: _.content.isStreaming
649
+ }
650
+ ) : _.content.message.content[0]?.type === "text" && // TaskTool interrupts use Progress messages without extra ⎿
437
651
  // since <Message /> component already adds the margin
438
652
  _.content.message.content[0].text === INTERRUPT_MESSAGE ? /* @__PURE__ */ React.createElement(
439
653
  Message,
@@ -472,48 +686,50 @@ function REPL({
472
686
  }
473
687
  )
474
688
  }
475
- ) : /* @__PURE__ */ React.createElement(
476
- Message,
477
- {
478
- message: _,
479
- messages: normalizedMessages,
480
- addMargin: true,
481
- tools,
482
- verbose,
483
- debug,
484
- erroredToolUseIDs,
485
- inProgressToolUseIDs,
486
- shouldAnimate: !toolJSX && !toolUseConfirm && !isMessageSelectorVisible && (!toolUseID || inProgressToolUseIDs.has(toolUseID)),
487
- shouldShowDot: true,
488
- unresolvedToolUseIDs
489
- }
490
- );
491
- const type = shouldRenderStatically(
492
- _,
493
- normalizedMessages,
689
+ )
690
+ ) : /* @__PURE__ */ React.createElement(
691
+ Message,
692
+ {
693
+ message: _,
694
+ messages: normalizedMessages,
695
+ addMargin: true,
696
+ tools,
697
+ verbose,
698
+ debug,
699
+ erroredToolUseIDs,
700
+ inProgressToolUseIDs,
701
+ shouldAnimate: !toolJSX && !toolUseConfirm && !isMessageSelectorVisible && (!toolUseID || inProgressToolUseIDs.has(toolUseID)),
702
+ shouldShowDot: true,
494
703
  unresolvedToolUseIDs
495
- ) ? "static" : "transient";
496
- if (debug) {
497
- return {
498
- type,
499
- jsx: /* @__PURE__ */ React.createElement(
500
- Box,
501
- {
502
- borderStyle: "single",
503
- borderColor: type === "static" ? "green" : "red",
504
- key: _.uuid,
505
- width: "100%"
506
- },
507
- message
508
- )
509
- };
510
704
  }
511
- return {
705
+ );
706
+ const type = shouldRenderStatically(
707
+ _,
708
+ normalizedMessages,
709
+ unresolvedToolUseIDs
710
+ ) ? "static" : "transient";
711
+ if (debug) {
712
+ result.push({
713
+ type,
714
+ jsx: /* @__PURE__ */ React.createElement(
715
+ Box,
716
+ {
717
+ borderStyle: "single",
718
+ borderColor: type === "static" ? "green" : "red",
719
+ key: _.uuid,
720
+ width: "100%"
721
+ },
722
+ message
723
+ )
724
+ });
725
+ } else {
726
+ result.push({
512
727
  type,
513
728
  jsx: /* @__PURE__ */ React.createElement(Box, { key: _.uuid, width: "100%" }, message)
514
- };
515
- })
516
- ];
729
+ });
730
+ }
731
+ }
732
+ return result;
517
733
  }, [
518
734
  forkNumber,
519
735
  normalizedMessages,
@@ -528,28 +744,120 @@ function REPL({
528
744
  unresolvedToolUseIDs,
529
745
  mcpClients,
530
746
  isDefaultModel,
531
- isResumedConversation
747
+ isResumedConversation,
748
+ // V1+ dependencies
749
+ messageGroups,
750
+ getGroupForMessage,
751
+ getGroupForToolUse,
752
+ shouldGroupBeStatic,
753
+ displayConfig,
754
+ agentTranscripts,
755
+ toolOutputs
532
756
  ]);
533
757
  const showingCostDialog = !isLoading && showCostDialog;
758
+ const { staticItems, dynamicItems } = useMemo(() => {
759
+ const staticItems2 = [];
760
+ const dynamicItems2 = [];
761
+ for (const item of messagesJSX) {
762
+ if (item.type === "static") {
763
+ const key = item.jsx.key?.toString() || `static-${staticItems2.length}`;
764
+ staticItems2.push({ id: key, jsx: item.jsx });
765
+ } else if (item.type === "transient") {
766
+ dynamicItems2.push(item);
767
+ }
768
+ }
769
+ return { staticItems: staticItems2, dynamicItems: dynamicItems2 };
770
+ }, [messagesJSX]);
771
+ const handleShowMessageSelector = useCallback(() => {
772
+ setIsMessageSelectorVisible((prev) => !prev);
773
+ }, []);
774
+ const handleToggleTodoPanel = useCallback(() => {
775
+ setIsTodoPanelVisible((prev) => !prev);
776
+ }, []);
777
+ const handleToggleBackgroundPanel = useCallback(() => {
778
+ setShowBackgroundPanel((prev) => !prev);
779
+ }, []);
780
+ const handleModelChange = useCallback(() => {
781
+ setForkNumber((prev) => prev + 1);
782
+ }, []);
783
+ const handleToggleVerbose = useCallback(async (newVerbose) => {
784
+ const message = `${getVerboseLabel(newVerbose)} (Ctrl+O)`;
785
+ setVerboseToggleMessage(message);
786
+ setTimeout(() => setVerboseToggleMessage(null), 2e3);
787
+ await clearTerminal();
788
+ setVerbose(newVerbose);
789
+ setForkNumber((prev) => prev + 1);
790
+ }, []);
791
+ const handleQueueAwareQuery = useCallback(
792
+ async (newMessages, abortController2) => {
793
+ if (!isLoading) {
794
+ return onQuery(newMessages, abortController2);
795
+ }
796
+ const userMessage = newMessages.find((m) => m.type === "user");
797
+ if (userMessage && userMessage.type === "user") {
798
+ const promptText = typeof userMessage.message.content === "string" ? userMessage.message.content : "";
799
+ if (promptText) {
800
+ setQueuedPrompts((prev) => [...prev, promptText]);
801
+ }
802
+ }
803
+ },
804
+ [isLoading]
805
+ );
806
+ useEffect(() => {
807
+ processNextQueuedPromptRef.current = async () => {
808
+ if (queuedPrompts.length === 0) return;
809
+ const nextPrompt = queuedPrompts[0];
810
+ setQueuedPrompts((prev) => prev.slice(1));
811
+ if (!nextPrompt) return;
812
+ const userMessage = {
813
+ type: "user",
814
+ uuid: randomUUID(),
815
+ message: {
816
+ role: "user",
817
+ content: nextPrompt
818
+ }
819
+ };
820
+ setIsLoading(true);
821
+ const newAbortController = new AbortController();
822
+ setAbortController(newAbortController);
823
+ await onQuery([userMessage], newAbortController);
824
+ };
825
+ }, [queuedPrompts]);
534
826
  return /* @__PURE__ */ React.createElement(
535
827
  PermissionProvider,
536
828
  {
537
829
  isBypassPermissionsModeAvailable: !safeMode,
538
- children: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ModeIndicator, null), /* @__PURE__ */ React.createElement(React.Fragment, { key: `static-messages-${forkNumber}` }, /* @__PURE__ */ React.createElement(
830
+ children: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(React.Fragment, { key: `mode-indicator-${forkNumber}` }, /* @__PURE__ */ React.createElement(ModeIndicator, null)), /* @__PURE__ */ React.createElement(React.Fragment, { key: `static-wrapper-${forkNumber}` }, /* @__PURE__ */ React.createElement(
539
831
  Static,
540
832
  {
541
- items: messagesJSX.filter((_) => _.type === "static"),
542
- children: (item) => item.jsx
833
+ items: staticItems,
834
+ children: (item) => /* @__PURE__ */ React.createElement(React.Fragment, { key: item.id }, item.jsx)
543
835
  }
544
- )), messagesJSX.filter((_) => _.type === "transient").map((_) => _.jsx), /* @__PURE__ */ React.createElement(
836
+ )), /* @__PURE__ */ React.createElement(React.Fragment, { key: `dynamic-messages-${forkNumber}` }, dynamicItems.map((item) => item.jsx)), /* @__PURE__ */ React.createElement(
545
837
  Box,
546
838
  {
839
+ key: `transient-ui-${forkNumber}`,
547
840
  borderColor: "red",
548
841
  borderStyle: debug ? "single" : void 0,
549
842
  flexDirection: "column",
550
843
  width: "100%"
551
844
  },
552
- !toolJSX && !toolUseConfirm && !binaryFeedbackContext && isLoading && /* @__PURE__ */ React.createElement(Spinner, null),
845
+ !isResizeClearing && !toolJSX && !toolUseConfirm && !binaryFeedbackContext && /* @__PURE__ */ React.createElement(
846
+ TodoPanel,
847
+ {
848
+ todos: getTodos(),
849
+ isVisible: isTodoPanelVisible,
850
+ isLoading,
851
+ showTodoList: isTodoPanelVisible
852
+ }
853
+ ),
854
+ !isResizeClearing && !isLoading && !toolJSX && !toolUseConfirm && !binaryFeedbackContext && /* @__PURE__ */ React.createElement(
855
+ TurnCompletionIndicator,
856
+ {
857
+ durationMs: lastTurnDurationMs,
858
+ isVisible: lastTurnDurationMs !== null
859
+ }
860
+ ),
553
861
  toolJSX ? toolJSX.jsx : null,
554
862
  !toolJSX && binaryFeedbackContext && !isMessageSelectorVisible && /* @__PURE__ */ React.createElement(
555
863
  BinaryFeedback,
@@ -599,15 +907,6 @@ function REPL({
599
907
  }
600
908
  ),
601
909
  !toolUseConfirm && !toolJSX?.shouldHidePromptInput && shouldShowPromptInput && !isMessageSelectorVisible && !binaryFeedbackContext && !askUserQuestionContext && !showingCostDialog && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
602
- TodoPanel,
603
- {
604
- todos: getTodos(),
605
- isVisible: isTodoPanelVisible,
606
- elapsedTime: Math.floor((Date.now() - startTime) / 1e3),
607
- tokenCount: 0,
608
- isLoading
609
- }
610
- ), /* @__PURE__ */ React.createElement(
611
910
  BackgroundTasksPanel,
612
911
  {
613
912
  shells: backgroundShells,
@@ -632,6 +931,7 @@ function REPL({
632
931
  onQuery,
633
932
  debug,
634
933
  verbose,
934
+ verboseToggleMessage,
635
935
  messages,
636
936
  setToolJSX,
637
937
  input: inputValue,
@@ -642,21 +942,30 @@ function REPL({
642
942
  onSubmitCountChange: setSubmitCount,
643
943
  setIsLoading,
644
944
  setAbortController,
645
- onShowMessageSelector: () => setIsMessageSelectorVisible((prev) => !prev),
945
+ onShowMessageSelector: handleShowMessageSelector,
646
946
  setForkConvoWithMessagesOnTheNextRender,
647
947
  readFileTimestamps: readFileTimestamps.current,
648
948
  abortController,
649
- onModelChange: () => setForkNumber((prev) => prev + 1),
949
+ onModelChange: handleModelChange,
650
950
  onRollbackConversation: rollbackConversation,
651
- onToggleTodoPanel: () => setIsTodoPanelVisible((prev) => !prev),
652
- onToggleVerbose: () => setVerbose((prev) => !prev),
653
- onToggleBackgroundPanel: () => setShowBackgroundPanel((prev) => !prev),
951
+ onToggleTodoPanel: handleToggleTodoPanel,
952
+ onToggleVerbose: handleToggleVerbose,
953
+ onToggleBackgroundPanel: handleToggleBackgroundPanel,
654
954
  backgroundShellCount: backgroundShells.filter((s) => s.status === "running").length,
655
955
  isBackgroundPanelOpen: showBackgroundPanel,
656
- fallbackMode
956
+ fallbackMode,
957
+ queuedPrompts,
958
+ onQueuePrompt: (prompt) => setQueuedPrompts((prev) => [...prev, prompt]),
959
+ onPopQueuedPrompt: () => {
960
+ if (queuedPrompts.length === 0) return void 0;
961
+ const lastPrompt = queuedPrompts[queuedPrompts.length - 1];
962
+ setQueuedPrompts((prev) => prev.slice(0, -1));
963
+ return lastPrompt;
964
+ },
965
+ onInterrupt
657
966
  }
658
967
  ))
659
- ), isMessageSelectorVisible && /* @__PURE__ */ React.createElement(
968
+ ), isMessageSelectorVisible && /* @__PURE__ */ React.createElement(React.Fragment, { key: `message-selector-wrapper-${forkNumber}` }, /* @__PURE__ */ React.createElement(
660
969
  MessageSelector,
661
970
  {
662
971
  erroredToolUseIDs,
@@ -682,7 +991,7 @@ function REPL({
682
991
  onEscape: () => setIsMessageSelectorVisible(false),
683
992
  tools
684
993
  }
685
- ), /* @__PURE__ */ React.createElement(Newline, null))
994
+ )), /* @__PURE__ */ React.createElement(Newline, null))
686
995
  }
687
996
  );
688
997
  }