@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
@@ -0,0 +1,143 @@
1
+ class ToolExecutor {
2
+ permissionEngine;
3
+ constructor(permissionEngine) {
4
+ this.permissionEngine = permissionEngine;
5
+ }
6
+ /**
7
+ * Set the permission engine
8
+ */
9
+ setPermissionEngine(engine) {
10
+ this.permissionEngine = engine;
11
+ }
12
+ /**
13
+ * Execute a tool
14
+ */
15
+ async *execute(tool, input, context, options = {}) {
16
+ const startTime = Date.now();
17
+ try {
18
+ if (!options.skipValidation) {
19
+ const validationResult = this.validateInput(tool, input, context);
20
+ if (!validationResult.result) {
21
+ yield {
22
+ type: "error",
23
+ error: new Error(
24
+ validationResult.message || "Input validation failed"
25
+ )
26
+ };
27
+ return;
28
+ }
29
+ }
30
+ if (!options.skipPermissionCheck && this.permissionEngine) {
31
+ const permissionResult = await this.checkPermission(
32
+ tool,
33
+ input,
34
+ context,
35
+ options.permissionContext
36
+ );
37
+ if (!permissionResult.allowed) {
38
+ yield {
39
+ type: "error",
40
+ error: new Error(permissionResult.reason || "Permission denied")
41
+ };
42
+ return;
43
+ }
44
+ if (permissionResult.promptUser) {
45
+ yield {
46
+ type: "result",
47
+ resultForAssistant: permissionResult.message || "Permission required"
48
+ };
49
+ return;
50
+ }
51
+ }
52
+ const generator = tool.call(input, context);
53
+ if (options.timeout) {
54
+ const timeoutPromise = new Promise((_, reject) => {
55
+ setTimeout(
56
+ () => reject(
57
+ new Error(
58
+ `Tool execution timed out after ${options.timeout}ms`
59
+ )
60
+ ),
61
+ options.timeout
62
+ );
63
+ });
64
+ for await (const result of generator) {
65
+ if (Date.now() - startTime > options.timeout) {
66
+ yield {
67
+ type: "error",
68
+ error: new Error(
69
+ `Tool execution timed out after ${options.timeout}ms`
70
+ )
71
+ };
72
+ return;
73
+ }
74
+ yield result;
75
+ }
76
+ } else {
77
+ for await (const result of generator) {
78
+ yield result;
79
+ }
80
+ }
81
+ } catch (error) {
82
+ yield {
83
+ type: "error",
84
+ error: error instanceof Error ? error : new Error(String(error))
85
+ };
86
+ }
87
+ }
88
+ /**
89
+ * Validate tool input
90
+ */
91
+ validateInput(tool, input, context) {
92
+ const schemaResult = tool.inputSchema.safeParse(input);
93
+ if (!schemaResult.success) {
94
+ return {
95
+ result: false,
96
+ message: `Input validation failed: ${schemaResult.error.message}`
97
+ };
98
+ }
99
+ if (tool.validateInput) {
100
+ const customResult = tool.validateInput(input, context);
101
+ if (customResult instanceof Promise) {
102
+ return { result: true };
103
+ }
104
+ return customResult;
105
+ }
106
+ return { result: true };
107
+ }
108
+ /**
109
+ * Check tool permissions
110
+ */
111
+ async checkPermission(tool, input, context, extra) {
112
+ if (!this.permissionEngine) {
113
+ return { allowed: true };
114
+ }
115
+ const permissionContext = {
116
+ tool,
117
+ input,
118
+ toolUseContext: context,
119
+ allowedTools: context.options?.allowedTools || [],
120
+ safeMode: context.options?.safeMode,
121
+ planMode: context.options?.planMode,
122
+ agentId: context.options?.agentId,
123
+ ...extra
124
+ };
125
+ return this.permissionEngine.checkPermission(permissionContext);
126
+ }
127
+ }
128
+ let globalExecutor = null;
129
+ function getToolExecutor() {
130
+ if (!globalExecutor) {
131
+ globalExecutor = new ToolExecutor();
132
+ }
133
+ return globalExecutor;
134
+ }
135
+ function resetToolExecutor() {
136
+ globalExecutor = null;
137
+ }
138
+ export {
139
+ ToolExecutor,
140
+ getToolExecutor,
141
+ resetToolExecutor
142
+ };
143
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/core/tools/executor.ts"],
4
+ "sourcesContent": ["/**\n * Tool Executor\n *\n * Handles tool execution with validation, permission checking, and error handling.\n */\n\nimport type {\n RegisterableTool,\n ToolExecutionContext,\n ToolExecutionResult,\n} from './types'\nimport type { PermissionEngine } from '../permissions/engine/permissionEngine'\nimport type { PermissionContext } from '../permissions/engine/types'\n\n/**\n * Execution options\n */\nexport interface ExecutionOptions {\n /** Skip permission check */\n skipPermissionCheck?: boolean\n\n /** Skip input validation */\n skipValidation?: boolean\n\n /** Timeout in milliseconds */\n timeout?: number\n\n /** Custom permission context data */\n permissionContext?: Partial<PermissionContext>\n}\n\n/**\n * Tool Executor\n *\n * Executes tools with proper validation and permission checking.\n */\nexport class ToolExecutor {\n private permissionEngine?: PermissionEngine\n\n constructor(permissionEngine?: PermissionEngine) {\n this.permissionEngine = permissionEngine\n }\n\n /**\n * Set the permission engine\n */\n setPermissionEngine(engine: PermissionEngine): void {\n this.permissionEngine = engine\n }\n\n /**\n * Execute a tool\n */\n async *execute<TInput, TOutput>(\n tool: RegisterableTool<TInput, TOutput>,\n input: TInput,\n context: ToolExecutionContext,\n options: ExecutionOptions = {},\n ): AsyncGenerator<ToolExecutionResult<TOutput>> {\n const startTime = Date.now()\n\n try {\n // Step 1: Validate input\n if (!options.skipValidation) {\n const validationResult = this.validateInput(tool, input, context)\n if (!validationResult.result) {\n yield {\n type: 'error',\n error: new Error(\n validationResult.message || 'Input validation failed',\n ),\n }\n return\n }\n }\n\n // Step 2: Check permissions\n if (!options.skipPermissionCheck && this.permissionEngine) {\n const permissionResult = await this.checkPermission(\n tool,\n input as Record<string, unknown>,\n context,\n options.permissionContext,\n )\n\n if (!permissionResult.allowed) {\n yield {\n type: 'error',\n error: new Error(permissionResult.reason || 'Permission denied'),\n }\n return\n }\n\n // Handle prompting user case\n if (permissionResult.promptUser) {\n yield {\n type: 'result',\n resultForAssistant:\n permissionResult.message || 'Permission required',\n }\n return\n }\n }\n\n // Step 3: Execute tool\n const generator = tool.call(input, context)\n\n // Step 4: Handle timeout if specified\n if (options.timeout) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(\n () =>\n reject(\n new Error(\n `Tool execution timed out after ${options.timeout}ms`,\n ),\n ),\n options.timeout,\n )\n })\n\n // Yield results with timeout checking\n for await (const result of generator) {\n // Check if we've exceeded timeout\n if (Date.now() - startTime > options.timeout) {\n yield {\n type: 'error',\n error: new Error(\n `Tool execution timed out after ${options.timeout}ms`,\n ),\n }\n return\n }\n yield result\n }\n } else {\n // No timeout, just yield results\n for await (const result of generator) {\n yield result\n }\n }\n } catch (error) {\n yield {\n type: 'error',\n error: error instanceof Error ? error : new Error(String(error)),\n }\n }\n }\n\n /**\n * Validate tool input\n */\n private validateInput<TInput>(\n tool: RegisterableTool<TInput>,\n input: TInput,\n context: ToolExecutionContext,\n ): { result: boolean; message?: string } {\n // Schema validation\n const schemaResult = tool.inputSchema.safeParse(input)\n if (!schemaResult.success) {\n return {\n result: false,\n message: `Input validation failed: ${schemaResult.error.message}`,\n }\n }\n\n // Custom validation\n if (tool.validateInput) {\n const customResult = tool.validateInput(input, context)\n if (customResult instanceof Promise) {\n // For sync executor, we can't await here\n // This should be handled by execute() method\n return { result: true }\n }\n return customResult\n }\n\n return { result: true }\n }\n\n /**\n * Check tool permissions\n */\n private async checkPermission(\n tool: RegisterableTool,\n input: Record<string, unknown>,\n context: ToolExecutionContext,\n extra?: Partial<PermissionContext>,\n ): Promise<{\n allowed: boolean\n reason?: string\n message?: string\n promptUser?: boolean\n }> {\n if (!this.permissionEngine) {\n return { allowed: true }\n }\n\n const permissionContext: PermissionContext = {\n tool: tool as any,\n input,\n toolUseContext: context as any,\n allowedTools: (context.options?.allowedTools as string[]) || [],\n safeMode: context.options?.safeMode,\n planMode: context.options?.planMode,\n agentId: context.options?.agentId,\n ...extra,\n }\n\n return this.permissionEngine.checkPermission(permissionContext)\n }\n}\n\n// Global singleton instance\nlet globalExecutor: ToolExecutor | null = null\n\n/**\n * Get the global tool executor instance\n */\nexport function getToolExecutor(): ToolExecutor {\n if (!globalExecutor) {\n globalExecutor = new ToolExecutor()\n }\n return globalExecutor\n}\n\n/**\n * Reset the global tool executor (for testing)\n */\nexport function resetToolExecutor(): void {\n globalExecutor = null\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,15 @@
1
+ import { ToolRegistry, getToolRegistry, resetToolRegistry } from "./registry.js";
2
+ import {
3
+ ToolExecutor,
4
+ getToolExecutor,
5
+ resetToolExecutor
6
+ } from "./executor.js";
7
+ export {
8
+ ToolExecutor,
9
+ ToolRegistry,
10
+ getToolExecutor,
11
+ getToolRegistry,
12
+ resetToolExecutor,
13
+ resetToolRegistry
14
+ };
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/core/tools/index.ts"],
4
+ "sourcesContent": ["/**\n * Core Tools Module\n *\n * Tool registry, executor, and type definitions.\n */\n\n// Types\nexport type {\n ToolCategory,\n ToolMetadata,\n ToolExecutionContext,\n ToolExecutionResult,\n RegisterableTool,\n} from './types'\n\n// Registry\nexport { ToolRegistry, getToolRegistry, resetToolRegistry } from './registry'\n\n// Executor\nexport {\n ToolExecutor,\n getToolExecutor,\n resetToolExecutor,\n type ExecutionOptions,\n} from './executor'\n"],
5
+ "mappings": "AAgBA,SAAS,cAAc,iBAAiB,yBAAyB;AAGjE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;",
6
+ "names": []
7
+ }
@@ -0,0 +1,183 @@
1
+ class ToolRegistry {
2
+ tools = /* @__PURE__ */ new Map();
3
+ metadata = /* @__PURE__ */ new Map();
4
+ aliases = /* @__PURE__ */ new Map();
5
+ /**
6
+ * Register a tool
7
+ */
8
+ register(tool, meta) {
9
+ const name = tool.name;
10
+ this.tools.set(name, tool);
11
+ const metadata = {
12
+ name,
13
+ displayName: tool.userFacingName?.() || name,
14
+ isReadOnly: tool.isReadOnly?.() ?? false,
15
+ needsPermissions: tool.needsPermissions?.() ?? true,
16
+ isConcurrencySafe: tool.isConcurrencySafe?.() ?? false,
17
+ ...meta
18
+ };
19
+ this.metadata.set(name, metadata);
20
+ if (metadata.aliases) {
21
+ for (const alias of metadata.aliases) {
22
+ this.aliases.set(alias, name);
23
+ }
24
+ }
25
+ }
26
+ /**
27
+ * Register multiple tools
28
+ */
29
+ registerAll(tools) {
30
+ for (const tool of tools) {
31
+ this.register(tool);
32
+ }
33
+ }
34
+ /**
35
+ * Unregister a tool
36
+ */
37
+ unregister(name) {
38
+ const meta = this.metadata.get(name);
39
+ if (meta?.aliases) {
40
+ for (const alias of meta.aliases) {
41
+ this.aliases.delete(alias);
42
+ }
43
+ }
44
+ this.metadata.delete(name);
45
+ return this.tools.delete(name);
46
+ }
47
+ /**
48
+ * Get a tool by name or alias
49
+ */
50
+ get(nameOrAlias) {
51
+ const tool = this.tools.get(nameOrAlias);
52
+ if (tool) return tool;
53
+ const realName = this.aliases.get(nameOrAlias);
54
+ if (realName) {
55
+ return this.tools.get(realName);
56
+ }
57
+ return void 0;
58
+ }
59
+ /**
60
+ * Check if a tool exists
61
+ */
62
+ has(nameOrAlias) {
63
+ return this.tools.has(nameOrAlias) || this.aliases.has(nameOrAlias);
64
+ }
65
+ /**
66
+ * Get all tools
67
+ */
68
+ getAll() {
69
+ return Array.from(this.tools.values());
70
+ }
71
+ /**
72
+ * Get all tool names
73
+ */
74
+ getNames() {
75
+ return Array.from(this.tools.keys());
76
+ }
77
+ /**
78
+ * Get tools by category
79
+ */
80
+ getByCategory(category) {
81
+ const results = [];
82
+ for (const [name, meta] of this.metadata.entries()) {
83
+ if (meta.category === category) {
84
+ const tool = this.tools.get(name);
85
+ if (tool) results.push(tool);
86
+ }
87
+ }
88
+ return results;
89
+ }
90
+ /**
91
+ * Get tools by tag
92
+ */
93
+ getByTag(tag) {
94
+ const results = [];
95
+ for (const [name, meta] of this.metadata.entries()) {
96
+ if (meta.tags?.includes(tag)) {
97
+ const tool = this.tools.get(name);
98
+ if (tool) results.push(tool);
99
+ }
100
+ }
101
+ return results;
102
+ }
103
+ /**
104
+ * Get enabled tools
105
+ */
106
+ async getEnabled() {
107
+ const results = [];
108
+ for (const tool of this.tools.values()) {
109
+ if (tool.isEnabled) {
110
+ const enabled = await Promise.resolve(tool.isEnabled());
111
+ if (enabled) {
112
+ results.push(tool);
113
+ }
114
+ } else {
115
+ results.push(tool);
116
+ }
117
+ }
118
+ return results;
119
+ }
120
+ /**
121
+ * Get read-only tools
122
+ */
123
+ getReadOnly() {
124
+ const results = [];
125
+ for (const tool of this.tools.values()) {
126
+ if (tool.isReadOnly?.()) {
127
+ results.push(tool);
128
+ }
129
+ }
130
+ return results;
131
+ }
132
+ /**
133
+ * Get tool metadata
134
+ */
135
+ getMetadata(name) {
136
+ const meta = this.metadata.get(name);
137
+ if (meta) return meta;
138
+ const realName = this.aliases.get(name);
139
+ if (realName) {
140
+ return this.metadata.get(realName);
141
+ }
142
+ return void 0;
143
+ }
144
+ /**
145
+ * Update tool metadata
146
+ */
147
+ updateMetadata(name, update) {
148
+ const existing = this.metadata.get(name);
149
+ if (!existing) return false;
150
+ this.metadata.set(name, { ...existing, ...update });
151
+ return true;
152
+ }
153
+ /**
154
+ * Get count of registered tools
155
+ */
156
+ get size() {
157
+ return this.tools.size;
158
+ }
159
+ /**
160
+ * Clear all tools
161
+ */
162
+ clear() {
163
+ this.tools.clear();
164
+ this.metadata.clear();
165
+ this.aliases.clear();
166
+ }
167
+ }
168
+ let globalRegistry = null;
169
+ function getToolRegistry() {
170
+ if (!globalRegistry) {
171
+ globalRegistry = new ToolRegistry();
172
+ }
173
+ return globalRegistry;
174
+ }
175
+ function resetToolRegistry() {
176
+ globalRegistry = null;
177
+ }
178
+ export {
179
+ ToolRegistry,
180
+ getToolRegistry,
181
+ resetToolRegistry
182
+ };
183
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/core/tools/registry.ts"],
4
+ "sourcesContent": ["/**\n * Tool Registry\n *\n * Centralized registry for tool management.\n */\n\nimport type { RegisterableTool, ToolCategory, ToolMetadata } from './types'\n\n/**\n * Tool Registry\n *\n * Manages registration and lookup of tools.\n */\nexport class ToolRegistry {\n private tools: Map<string, RegisterableTool> = new Map()\n private metadata: Map<string, ToolMetadata> = new Map()\n private aliases: Map<string, string> = new Map()\n\n /**\n * Register a tool\n */\n register(tool: RegisterableTool, meta?: Partial<ToolMetadata>): void {\n const name = tool.name\n\n // Store tool\n this.tools.set(name, tool)\n\n // Build metadata\n const metadata: ToolMetadata = {\n name,\n displayName: tool.userFacingName?.() || name,\n isReadOnly: tool.isReadOnly?.() ?? false,\n needsPermissions: tool.needsPermissions?.() ?? true,\n isConcurrencySafe: tool.isConcurrencySafe?.() ?? false,\n ...meta,\n }\n this.metadata.set(name, metadata)\n\n // Register aliases\n if (metadata.aliases) {\n for (const alias of metadata.aliases) {\n this.aliases.set(alias, name)\n }\n }\n }\n\n /**\n * Register multiple tools\n */\n registerAll(tools: RegisterableTool[]): void {\n for (const tool of tools) {\n this.register(tool)\n }\n }\n\n /**\n * Unregister a tool\n */\n unregister(name: string): boolean {\n const meta = this.metadata.get(name)\n\n // Remove aliases\n if (meta?.aliases) {\n for (const alias of meta.aliases) {\n this.aliases.delete(alias)\n }\n }\n\n // Remove from registry\n this.metadata.delete(name)\n return this.tools.delete(name)\n }\n\n /**\n * Get a tool by name or alias\n */\n get(nameOrAlias: string): RegisterableTool | undefined {\n // Try direct lookup first\n const tool = this.tools.get(nameOrAlias)\n if (tool) return tool\n\n // Try alias lookup\n const realName = this.aliases.get(nameOrAlias)\n if (realName) {\n return this.tools.get(realName)\n }\n\n return undefined\n }\n\n /**\n * Check if a tool exists\n */\n has(nameOrAlias: string): boolean {\n return this.tools.has(nameOrAlias) || this.aliases.has(nameOrAlias)\n }\n\n /**\n * Get all tools\n */\n getAll(): RegisterableTool[] {\n return Array.from(this.tools.values())\n }\n\n /**\n * Get all tool names\n */\n getNames(): string[] {\n return Array.from(this.tools.keys())\n }\n\n /**\n * Get tools by category\n */\n getByCategory(category: ToolCategory): RegisterableTool[] {\n const results: RegisterableTool[] = []\n\n for (const [name, meta] of this.metadata.entries()) {\n if (meta.category === category) {\n const tool = this.tools.get(name)\n if (tool) results.push(tool)\n }\n }\n\n return results\n }\n\n /**\n * Get tools by tag\n */\n getByTag(tag: string): RegisterableTool[] {\n const results: RegisterableTool[] = []\n\n for (const [name, meta] of this.metadata.entries()) {\n if (meta.tags?.includes(tag)) {\n const tool = this.tools.get(name)\n if (tool) results.push(tool)\n }\n }\n\n return results\n }\n\n /**\n * Get enabled tools\n */\n async getEnabled(): Promise<RegisterableTool[]> {\n const results: RegisterableTool[] = []\n\n for (const tool of this.tools.values()) {\n if (tool.isEnabled) {\n const enabled = await Promise.resolve(tool.isEnabled())\n if (enabled) {\n results.push(tool)\n }\n } else {\n // No isEnabled means always enabled\n results.push(tool)\n }\n }\n\n return results\n }\n\n /**\n * Get read-only tools\n */\n getReadOnly(): RegisterableTool[] {\n const results: RegisterableTool[] = []\n\n for (const tool of this.tools.values()) {\n if (tool.isReadOnly?.()) {\n results.push(tool)\n }\n }\n\n return results\n }\n\n /**\n * Get tool metadata\n */\n getMetadata(name: string): ToolMetadata | undefined {\n // Try direct lookup\n const meta = this.metadata.get(name)\n if (meta) return meta\n\n // Try alias lookup\n const realName = this.aliases.get(name)\n if (realName) {\n return this.metadata.get(realName)\n }\n\n return undefined\n }\n\n /**\n * Update tool metadata\n */\n updateMetadata(name: string, update: Partial<ToolMetadata>): boolean {\n const existing = this.metadata.get(name)\n if (!existing) return false\n\n this.metadata.set(name, { ...existing, ...update })\n return true\n }\n\n /**\n * Get count of registered tools\n */\n get size(): number {\n return this.tools.size\n }\n\n /**\n * Clear all tools\n */\n clear(): void {\n this.tools.clear()\n this.metadata.clear()\n this.aliases.clear()\n }\n}\n\n// Global singleton instance\nlet globalRegistry: ToolRegistry | null = null\n\n/**\n * Get the global tool registry instance\n */\nexport function getToolRegistry(): ToolRegistry {\n if (!globalRegistry) {\n globalRegistry = new ToolRegistry()\n }\n return globalRegistry\n}\n\n/**\n * Reset the global tool registry (for testing)\n */\nexport function resetToolRegistry(): void {\n globalRegistry = null\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -1,5 +1,6 @@
1
1
  import chalk from "chalk";
2
2
  import { useEffect } from "react";
3
+ import signalExit from "signal-exit";
3
4
  import { formatDuration } from "./utils/format.js";
4
5
  import {
5
6
  getCurrentProjectConfig,
@@ -34,23 +35,30 @@ Total duration (API): ${formatDuration(STATE.totalAPIDuration)}
34
35
  Total duration (wall): ${formatDuration(getTotalDuration())}`
35
36
  );
36
37
  }
38
+ let exitHandlerRegistered = false;
37
39
  function useCostSummary() {
38
40
  useEffect(() => {
39
- const f = () => {
40
- process.stdout.write("\n" + formatTotalCost() + "\n");
41
- const projectConfig = getCurrentProjectConfig();
42
- saveCurrentProjectConfig({
43
- ...projectConfig,
44
- lastCost: STATE.totalCost,
45
- lastAPIDuration: STATE.totalAPIDuration,
46
- lastDuration: getTotalDuration(),
47
- lastSessionId: SESSION_ID
48
- });
49
- };
50
- process.on("exit", f);
51
- return () => {
52
- process.off("exit", f);
53
- };
41
+ if (exitHandlerRegistered) {
42
+ return;
43
+ }
44
+ exitHandlerRegistered = true;
45
+ signalExit(
46
+ () => {
47
+ process.stdout.write("\n" + formatTotalCost() + "\n");
48
+ try {
49
+ const projectConfig = getCurrentProjectConfig();
50
+ saveCurrentProjectConfig({
51
+ ...projectConfig,
52
+ lastCost: STATE.totalCost,
53
+ lastAPIDuration: STATE.totalAPIDuration,
54
+ lastDuration: getTotalDuration(),
55
+ lastSessionId: SESSION_ID
56
+ });
57
+ } catch {
58
+ }
59
+ },
60
+ { alwaysLast: true }
61
+ );
54
62
  }, []);
55
63
  }
56
64
  function round(number, precision) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/cost-tracker.ts"],
4
- "sourcesContent": ["import chalk from 'chalk'\nimport { useEffect } from 'react'\nimport { formatDuration } from './utils/format'\nimport {\n getCurrentProjectConfig,\n saveCurrentProjectConfig,\n} from '@utils/config'\nimport { SESSION_ID } from './utils/log'\n\n// DO NOT ADD MORE STATE HERE OR BORIS WILL CURSE YOU\nconst STATE: {\n totalCost: number\n totalAPIDuration: number\n startTime: number\n} = {\n totalCost: 0,\n totalAPIDuration: 0,\n startTime: Date.now(),\n}\n\nexport function addToTotalCost(cost: number, duration: number): void {\n STATE.totalCost += cost\n STATE.totalAPIDuration += duration\n}\n\nexport function getTotalCost(): number {\n return STATE.totalCost\n}\n\nexport function getTotalDuration(): number {\n return Date.now() - STATE.startTime\n}\n\nexport function getTotalAPIDuration(): number {\n return STATE.totalAPIDuration\n}\n\nfunction formatCost(cost: number): string {\n return `$${cost > 0.5 ? round(cost, 100).toFixed(2) : cost.toFixed(4)}`\n}\n\nexport function formatTotalCost(): string {\n return chalk.grey(\n `Total cost: ${formatCost(STATE.totalCost)}\nTotal duration (API): ${formatDuration(STATE.totalAPIDuration)}\nTotal duration (wall): ${formatDuration(getTotalDuration())}`,\n )\n}\n\nexport function useCostSummary(): void {\n useEffect(() => {\n const f = () => {\n process.stdout.write('\\n' + formatTotalCost() + '\\n')\n\n // Save last cost and duration to project config\n const projectConfig = getCurrentProjectConfig()\n saveCurrentProjectConfig({\n ...projectConfig,\n lastCost: STATE.totalCost,\n lastAPIDuration: STATE.totalAPIDuration,\n lastDuration: getTotalDuration(),\n lastSessionId: SESSION_ID,\n })\n }\n process.on('exit', f)\n return () => {\n process.off('exit', f)\n }\n }, [])\n}\n\nfunction round(number: number, precision: number): number {\n return Math.round(number * precision) / precision\n}\n\n// Only used in tests\nexport function resetStateForTests(): void {\n if (process.env.NODE_ENV !== 'test') {\n throw new Error('resetStateForTests can only be called in tests')\n }\n STATE.startTime = Date.now()\n STATE.totalCost = 0\n STATE.totalAPIDuration = 0\n}\n"],
5
- "mappings": "AAAA,OAAO,WAAW;AAClB,SAAS,iBAAiB;AAC1B,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAG3B,MAAM,QAIF;AAAA,EACF,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,WAAW,KAAK,IAAI;AACtB;AAEO,SAAS,eAAe,MAAc,UAAwB;AACnE,QAAM,aAAa;AACnB,QAAM,oBAAoB;AAC5B;AAEO,SAAS,eAAuB;AACrC,SAAO,MAAM;AACf;AAEO,SAAS,mBAA2B;AACzC,SAAO,KAAK,IAAI,IAAI,MAAM;AAC5B;AAEO,SAAS,sBAA8B;AAC5C,SAAO,MAAM;AACf;AAEA,SAAS,WAAW,MAAsB;AACxC,SAAO,IAAI,OAAO,MAAM,MAAM,MAAM,GAAG,EAAE,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;AACvE;AAEO,SAAS,kBAA0B;AACxC,SAAO,MAAM;AAAA,IACX,eAAe,WAAW,MAAM,SAAS,CAAC;AAAA,wBACtB,eAAe,MAAM,gBAAgB,CAAC;AAAA,yBACrC,eAAe,iBAAiB,CAAC,CAAC;AAAA,EACzD;AACF;AAEO,SAAS,iBAAuB;AACrC,YAAU,MAAM;AACd,UAAM,IAAI,MAAM;AACd,cAAQ,OAAO,MAAM,OAAO,gBAAgB,IAAI,IAAI;AAGpD,YAAM,gBAAgB,wBAAwB;AAC9C,+BAAyB;AAAA,QACvB,GAAG;AAAA,QACH,UAAU,MAAM;AAAA,QAChB,iBAAiB,MAAM;AAAA,QACvB,cAAc,iBAAiB;AAAA,QAC/B,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AACA,YAAQ,GAAG,QAAQ,CAAC;AACpB,WAAO,MAAM;AACX,cAAQ,IAAI,QAAQ,CAAC;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,CAAC;AACP;AAEA,SAAS,MAAM,QAAgB,WAA2B;AACxD,SAAO,KAAK,MAAM,SAAS,SAAS,IAAI;AAC1C;AAGO,SAAS,qBAA2B;AACzC,MAAI,QAAQ,IAAI,aAAa,QAAQ;AACnC,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,YAAY;AAClB,QAAM,mBAAmB;AAC3B;",
4
+ "sourcesContent": ["import chalk from 'chalk'\nimport { useEffect } from 'react'\nimport signalExit from 'signal-exit'\nimport { formatDuration } from './utils/format'\nimport {\n getCurrentProjectConfig,\n saveCurrentProjectConfig,\n} from '@utils/config'\nimport { SESSION_ID } from './utils/log'\n\n// DO NOT ADD MORE STATE HERE OR BORIS WILL CURSE YOU\nconst STATE: {\n totalCost: number\n totalAPIDuration: number\n startTime: number\n} = {\n totalCost: 0,\n totalAPIDuration: 0,\n startTime: Date.now(),\n}\n\nexport function addToTotalCost(cost: number, duration: number): void {\n STATE.totalCost += cost\n STATE.totalAPIDuration += duration\n}\n\nexport function getTotalCost(): number {\n return STATE.totalCost\n}\n\nexport function getTotalDuration(): number {\n return Date.now() - STATE.startTime\n}\n\nexport function getTotalAPIDuration(): number {\n return STATE.totalAPIDuration\n}\n\nfunction formatCost(cost: number): string {\n return `$${cost > 0.5 ? round(cost, 100).toFixed(2) : cost.toFixed(4)}`\n}\n\nexport function formatTotalCost(): string {\n return chalk.grey(\n `Total cost: ${formatCost(STATE.totalCost)}\nTotal duration (API): ${formatDuration(STATE.totalAPIDuration)}\nTotal duration (wall): ${formatDuration(getTotalDuration())}`,\n )\n}\n\n/**\n * useCostSummary - Register exit handler to display cost summary\n *\n * CRITICAL FIX: Use signal-exit with alwaysLast: true\n *\n * The problem was that Ink also uses signal-exit (with alwaysLast: false)\n * to clean up on exit. During Ink's cleanup, it may:\n * 1. Call onRender() one last time\n * 2. Use ansiEscapes.eraseLines() to clear previous output\n * 3. Or even call clearTerminal if output height >= terminal rows\n *\n * By using signal-exit with alwaysLast: true, we ensure our handler\n * runs AFTER Ink's cleanup, so our statistics are the last thing printed.\n */\n// Flag to ensure we only register once and never unregister\nlet exitHandlerRegistered = false\n\nexport function useCostSummary(): void {\n useEffect(() => {\n // Only register ONCE, and NEVER unregister\n if (exitHandlerRegistered) {\n return\n }\n exitHandlerRegistered = true\n\n // Use signal-exit with alwaysLast: true to run AFTER Ink's cleanup\n // This ensures our statistics are printed after Ink finishes its final render\n signalExit(\n () => {\n // Write statistics to stdout\n // Using stdout.write directly to avoid any Ink interception\n process.stdout.write('\\n' + formatTotalCost() + '\\n')\n\n // Save last cost and duration to project config\n try {\n const projectConfig = getCurrentProjectConfig()\n saveCurrentProjectConfig({\n ...projectConfig,\n lastCost: STATE.totalCost,\n lastAPIDuration: STATE.totalAPIDuration,\n lastDuration: getTotalDuration(),\n lastSessionId: SESSION_ID,\n })\n } catch {\n // Ignore errors during exit - config save is best-effort\n }\n },\n { alwaysLast: true },\n )\n\n // NO cleanup function - we NEVER want to unregister this handler\n }, [])\n}\n\nfunction round(number: number, precision: number): number {\n return Math.round(number * precision) / precision\n}\n\n// Only used in tests\nexport function resetStateForTests(): void {\n if (process.env.NODE_ENV !== 'test') {\n throw new Error('resetStateForTests can only be called in tests')\n }\n STATE.startTime = Date.now()\n STATE.totalCost = 0\n STATE.totalAPIDuration = 0\n}\n"],
5
+ "mappings": "AAAA,OAAO,WAAW;AAClB,SAAS,iBAAiB;AAC1B,OAAO,gBAAgB;AACvB,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAG3B,MAAM,QAIF;AAAA,EACF,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,WAAW,KAAK,IAAI;AACtB;AAEO,SAAS,eAAe,MAAc,UAAwB;AACnE,QAAM,aAAa;AACnB,QAAM,oBAAoB;AAC5B;AAEO,SAAS,eAAuB;AACrC,SAAO,MAAM;AACf;AAEO,SAAS,mBAA2B;AACzC,SAAO,KAAK,IAAI,IAAI,MAAM;AAC5B;AAEO,SAAS,sBAA8B;AAC5C,SAAO,MAAM;AACf;AAEA,SAAS,WAAW,MAAsB;AACxC,SAAO,IAAI,OAAO,MAAM,MAAM,MAAM,GAAG,EAAE,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;AACvE;AAEO,SAAS,kBAA0B;AACxC,SAAO,MAAM;AAAA,IACX,eAAe,WAAW,MAAM,SAAS,CAAC;AAAA,wBACtB,eAAe,MAAM,gBAAgB,CAAC;AAAA,yBACrC,eAAe,iBAAiB,CAAC,CAAC;AAAA,EACzD;AACF;AAiBA,IAAI,wBAAwB;AAErB,SAAS,iBAAuB;AACrC,YAAU,MAAM;AAEd,QAAI,uBAAuB;AACzB;AAAA,IACF;AACA,4BAAwB;AAIxB;AAAA,MACE,MAAM;AAGJ,gBAAQ,OAAO,MAAM,OAAO,gBAAgB,IAAI,IAAI;AAGpD,YAAI;AACF,gBAAM,gBAAgB,wBAAwB;AAC9C,mCAAyB;AAAA,YACvB,GAAG;AAAA,YACH,UAAU,MAAM;AAAA,YAChB,iBAAiB,MAAM;AAAA,YACvB,cAAc,iBAAiB;AAAA,YAC/B,eAAe;AAAA,UACjB,CAAC;AAAA,QACH,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,MACA,EAAE,YAAY,KAAK;AAAA,IACrB;AAAA,EAGF,GAAG,CAAC,CAAC;AACP;AAEA,SAAS,MAAM,QAAgB,WAA2B;AACxD,SAAO,KAAK,MAAM,SAAS,SAAS,IAAI;AAC1C;AAGO,SAAS,qBAA2B;AACzC,MAAI,QAAQ,IAAI,aAAa,QAAQ;AACnC,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,YAAY;AAClB,QAAM,mBAAmB;AAC3B;",
6
6
  "names": []
7
7
  }
@@ -1,11 +1,15 @@
1
1
  #!/usr/bin/env -S node --no-warnings=ExperimentalWarning --enable-source-maps
2
2
  process.env.DEV = "false";
3
+ import { EventEmitter } from "events";
4
+ EventEmitter.defaultMaxListeners = 20;
3
5
  import { fileURLToPath } from "node:url";
4
6
  import { dirname, join } from "node:path";
5
7
  import { existsSync } from "node:fs";
6
8
  import { initSentry } from "../services/sentry.js";
7
9
  import { PRODUCT_COMMAND, PRODUCT_NAME } from "../constants/product.js";
10
+ import { initGlobalErrorHandlers } from "../utils/globalErrorHandler.js";
8
11
  initSentry();
12
+ initGlobalErrorHandlers();
9
13
  try {
10
14
  if (!process.env.YOGA_WASM_PATH) {
11
15
  const __filename = fileURLToPath(import.meta.url);
@@ -59,6 +63,7 @@ import { getCommands } from "../commands.js";
59
63
  import { getNextAvailableLogForkNumber, loadLogList } from "../utils/log.js";
60
64
  import { loadMessagesFromLog } from "../utils/conversationRecovery.js";
61
65
  import { cleanupOldMessageFilesInBackground } from "../utils/cleanup.js";
66
+ import { runLogRotationInBackground, shouldRotate } from "../utils/logRotation.js";
62
67
  import {
63
68
  handleListApprovedTools,
64
69
  handleRemoveApprovedTool
@@ -70,8 +75,7 @@ import {
70
75
  parseEnvVars,
71
76
  removeMcpServer,
72
77
  getClients,
73
- ensureConfigScope,
74
- shutdownMCPClients
78
+ ensureConfigScope
75
79
  } from "../services/mcpClient.js";
76
80
  import { handleMcprcServerApprovals } from "../services/mcpServerApproval.js";
77
81
  import { cursorShow } from "ansi-escapes";
@@ -80,10 +84,16 @@ import {
80
84
  assertMinVersion,
81
85
  getUpdateCommandSuggestions
82
86
  } from "../utils/autoUpdater.js";
87
+ import {
88
+ initI18n,
89
+ setLanguage,
90
+ isLanguageSupported
91
+ } from "../i18n/index.js";
83
92
  import { gt } from "semver";
84
93
  import { CACHE_PATHS } from "../utils/log.js";
85
- import { PersistentShell } from "../utils/PersistentShell.js";
94
+ import { onShellCrash } from "../utils/PersistentShell.js";
86
95
  import { clearTerminal } from "../utils/terminal.js";
96
+ import { setupExitHandlers } from "../utils/exit.js";
87
97
  import { showInvalidConfigDialog } from "../components/InvalidConfigDialog.js";
88
98
  import { ConfigParseError } from "../utils/errors.js";
89
99
  import { grantReadPermissionForOriginalDir } from "../utils/permissions/filesystem.js";
@@ -204,6 +214,9 @@ async function setup(cwd2, safeMode) {
204
214
  return;
205
215
  }
206
216
  cleanupOldMessageFilesInBackground();
217
+ if (shouldRotate()) {
218
+ runLogRotationInBackground();
219
+ }
207
220
  getContext();
208
221
  const globalConfig = getGlobalConfig();
209
222
  if (globalConfig.iterm2KeyBindingInstalled === true && globalConfig.shiftEnterKeyBindingInstalled !== true) {
@@ -254,7 +267,24 @@ if (process.env.NODE_ENV !== "test") {
254
267
  });
255
268
  }
256
269
  async function main() {
270
+ const globalConfig = getGlobalConfig();
271
+ const configLang = globalConfig.language;
272
+ if (configLang && isLanguageSupported(configLang)) {
273
+ initI18n(configLang);
274
+ } else {
275
+ initI18n("en");
276
+ }
257
277
  initDebugLogger();
278
+ onShellCrash((code, signal) => {
279
+ console.error("");
280
+ console.error(
281
+ `\u26A0\uFE0F Shell process crashed unexpectedly (code: ${code}, signal: ${signal})`
282
+ );
283
+ console.error(
284
+ " Bash commands may fail. Try running /clear or restart the CLI."
285
+ );
286
+ console.error("");
287
+ });
258
288
  try {
259
289
  enableConfigs();
260
290
  try {
@@ -347,6 +377,10 @@ ${commandList}`
347
377
  "-r, --resume",
348
378
  "Select a previous conversation to resume",
349
379
  () => true
380
+ ).option(
381
+ "-l, --lang <language>",
382
+ "Set interface language (en, zh-CN)",
383
+ String
350
384
  ).action(
351
385
  async (prompt, {
352
386
  cwd: cwd2,
@@ -356,8 +390,12 @@ ${commandList}`
356
390
  print,
357
391
  safe,
358
392
  new: startNew,
359
- resume: selectResume
393
+ resume: selectResume,
394
+ lang
360
395
  }) => {
396
+ if (lang && isLanguageSupported(lang)) {
397
+ setLanguage(lang);
398
+ }
361
399
  await showSetupScreens(safe, print, rawModeSupported);
362
400
  await setup(cwd2, safe);
363
401
  assertMinVersion();
@@ -1184,45 +1222,7 @@ async function stdin() {
1184
1222
  for await (const chunk of process.stdin) data += chunk;
1185
1223
  return data;
1186
1224
  }
1187
- process.on("exit", () => {
1188
- resetCursor();
1189
- PersistentShell.getInstance().close();
1190
- });
1191
- let isShuttingDown = false;
1192
- async function gracefulExit(code = 0) {
1193
- if (isShuttingDown) return;
1194
- isShuttingDown = true;
1195
- try {
1196
- resetCursor();
1197
- } catch {
1198
- }
1199
- try {
1200
- PersistentShell.getInstance().close();
1201
- } catch {
1202
- }
1203
- try {
1204
- await shutdownMCPClients();
1205
- } catch {
1206
- }
1207
- process.exit(code);
1208
- }
1209
- process.on("SIGINT", () => {
1210
- gracefulExit(0);
1211
- });
1212
- process.on("SIGTERM", () => {
1213
- gracefulExit(0);
1214
- });
1215
- process.on("SIGBREAK", () => {
1216
- gracefulExit(0);
1217
- });
1218
- process.on("unhandledRejection", (err) => {
1219
- console.error("Unhandled rejection:", err);
1220
- gracefulExit(1);
1221
- });
1222
- process.on("uncaughtException", (err) => {
1223
- console.error("Uncaught exception:", err);
1224
- gracefulExit(1);
1225
- });
1225
+ setupExitHandlers();
1226
1226
  function resetCursor() {
1227
1227
  const terminal = process.stderr.isTTY ? process.stderr : process.stdout.isTTY ? process.stdout : void 0;
1228
1228
  terminal?.write(`\x1B[?25h${cursorShow}`);