@within-7/minto 0.1.7 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (601) 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 +73 -49
  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 +85 -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 +157 -0
  22. package/dist/commands/export.js.map +7 -0
  23. package/dist/commands/mcp-interactive.js +28 -18
  24. package/dist/commands/mcp-interactive.js.map +2 -2
  25. package/dist/commands/model.js +9 -7
  26. package/dist/commands/model.js.map +2 -2
  27. package/dist/commands/permissions.js +87 -0
  28. package/dist/commands/permissions.js.map +7 -0
  29. package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
  30. package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
  31. package/dist/commands/plugin/ConfirmDialog.js +2 -1
  32. package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
  33. package/dist/commands/plugin/ErrorView.js +2 -1
  34. package/dist/commands/plugin/ErrorView.js.map +2 -2
  35. package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
  36. package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
  37. package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
  38. package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
  39. package/dist/commands/plugin/MainMenu.js +2 -1
  40. package/dist/commands/plugin/MainMenu.js.map +2 -2
  41. package/dist/commands/plugin/MarketplaceManager.js +5 -4
  42. package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
  43. package/dist/commands/plugin/MarketplaceSelector.js +4 -3
  44. package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
  45. package/dist/commands/plugin/PlaceholderScreen.js +3 -2
  46. package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
  47. package/dist/commands/plugin/PluginBrowser.js +6 -5
  48. package/dist/commands/plugin/PluginBrowser.js.map +2 -2
  49. package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
  50. package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
  51. package/dist/commands/plugin/PluginDetailsManage.js +4 -3
  52. package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
  53. package/dist/commands/plugin.js +16 -15
  54. package/dist/commands/plugin.js.map +2 -2
  55. package/dist/commands/quit.js +3 -1
  56. package/dist/commands/quit.js.map +2 -2
  57. package/dist/commands/sandbox.js +105 -0
  58. package/dist/commands/sandbox.js.map +7 -0
  59. package/dist/commands/setup.js +2 -1
  60. package/dist/commands/setup.js.map +2 -2
  61. package/dist/commands/status.js +59 -0
  62. package/dist/commands/status.js.map +7 -0
  63. package/dist/commands/tasks.js +108 -0
  64. package/dist/commands/tasks.js.map +7 -0
  65. package/dist/commands/todos.js +123 -0
  66. package/dist/commands/todos.js.map +7 -0
  67. package/dist/commands/undo.js +245 -0
  68. package/dist/commands/undo.js.map +7 -0
  69. package/dist/commands.js +22 -2
  70. package/dist/commands.js.map +2 -2
  71. package/dist/components/AgentThinkingBlock.js +10 -18
  72. package/dist/components/AgentThinkingBlock.js.map +2 -2
  73. package/dist/components/AsciiLogo.js +7 -8
  74. package/dist/components/AsciiLogo.js.map +2 -2
  75. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
  76. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
  77. package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
  78. package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
  79. package/dist/components/BackgroundTasksPanel.js +78 -29
  80. package/dist/components/BackgroundTasksPanel.js.map +2 -2
  81. package/dist/components/BashStreamingProgress.js +24 -0
  82. package/dist/components/BashStreamingProgress.js.map +7 -0
  83. package/dist/components/CollapsibleHint.js +15 -0
  84. package/dist/components/CollapsibleHint.js.map +7 -0
  85. package/dist/components/Config.js +3 -2
  86. package/dist/components/Config.js.map +2 -2
  87. package/dist/components/ConsoleOAuthFlow.js +2 -1
  88. package/dist/components/ConsoleOAuthFlow.js.map +2 -2
  89. package/dist/components/Cost.js +2 -1
  90. package/dist/components/Cost.js.map +2 -2
  91. package/dist/components/FileEditToolUpdatedMessage.js +1 -1
  92. package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
  93. package/dist/components/HeaderBar.js +13 -8
  94. package/dist/components/HeaderBar.js.map +2 -2
  95. package/dist/components/HistorySearchOverlay.js +4 -3
  96. package/dist/components/HistorySearchOverlay.js.map +2 -2
  97. package/dist/components/HotkeyHelpPanel.js +134 -0
  98. package/dist/components/HotkeyHelpPanel.js.map +7 -0
  99. package/dist/components/InvalidConfigDialog.js +2 -1
  100. package/dist/components/InvalidConfigDialog.js.map +2 -2
  101. package/dist/components/Logo.js +24 -68
  102. package/dist/components/Logo.js.map +2 -2
  103. package/dist/components/MCPServerApprovalDialog.js +2 -1
  104. package/dist/components/MCPServerApprovalDialog.js.map +2 -2
  105. package/dist/components/MCPServerDialogCopy.js +2 -1
  106. package/dist/components/MCPServerDialogCopy.js.map +2 -2
  107. package/dist/components/MCPServerMultiselectDialog.js +2 -1
  108. package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
  109. package/dist/components/Message.js +23 -7
  110. package/dist/components/Message.js.map +3 -3
  111. package/dist/components/MessageSelector.js +4 -3
  112. package/dist/components/MessageSelector.js.map +2 -2
  113. package/dist/components/ModeIndicator.js +2 -1
  114. package/dist/components/ModeIndicator.js.map +2 -2
  115. package/dist/components/ModelConfig.js +20 -6
  116. package/dist/components/ModelConfig.js.map +2 -2
  117. package/dist/components/ModelListManager.js +7 -6
  118. package/dist/components/ModelListManager.js.map +2 -2
  119. package/dist/components/ModelSelector/ModelSelector.js +27 -14
  120. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  121. package/dist/components/Onboarding.js +22 -16
  122. package/dist/components/Onboarding.js.map +2 -2
  123. package/dist/components/OperationSummary.js +130 -0
  124. package/dist/components/OperationSummary.js.map +7 -0
  125. package/dist/components/ProgressBar.js +74 -0
  126. package/dist/components/ProgressBar.js.map +7 -0
  127. package/dist/components/PromptInput.js +210 -87
  128. package/dist/components/PromptInput.js.map +2 -2
  129. package/dist/components/RequestStatusIndicator.js +194 -0
  130. package/dist/components/RequestStatusIndicator.js.map +7 -0
  131. package/dist/components/SensitiveFileWarning.js +31 -0
  132. package/dist/components/SensitiveFileWarning.js.map +7 -0
  133. package/dist/components/Spinner.js +141 -27
  134. package/dist/components/Spinner.js.map +2 -2
  135. package/dist/components/SpinnerSymbol.js +21 -27
  136. package/dist/components/SpinnerSymbol.js.map +2 -2
  137. package/dist/components/StreamingBashOutput.js +9 -8
  138. package/dist/components/StreamingBashOutput.js.map +2 -2
  139. package/dist/components/StructuredDiff.js +6 -8
  140. package/dist/components/StructuredDiff.js.map +2 -2
  141. package/dist/components/SubagentBlock.js +5 -3
  142. package/dist/components/SubagentBlock.js.map +2 -2
  143. package/dist/components/SubagentProgress.js +17 -15
  144. package/dist/components/SubagentProgress.js.map +2 -2
  145. package/dist/components/TaskCard.js +30 -24
  146. package/dist/components/TaskCard.js.map +2 -2
  147. package/dist/components/TextInput.js +9 -1
  148. package/dist/components/TextInput.js.map +2 -2
  149. package/dist/components/TodoChangeBlock.js +1 -1
  150. package/dist/components/TodoChangeBlock.js.map +2 -2
  151. package/dist/components/TodoPanel.js +140 -31
  152. package/dist/components/TodoPanel.js.map +3 -3
  153. package/dist/components/TokenCounter.js +74 -0
  154. package/dist/components/TokenCounter.js.map +7 -0
  155. package/dist/components/TokenWarning.js +2 -1
  156. package/dist/components/TokenWarning.js.map +2 -2
  157. package/dist/components/ToolUseLoader.js +2 -2
  158. package/dist/components/ToolUseLoader.js.map +2 -2
  159. package/dist/components/TreeConnector.js +26 -0
  160. package/dist/components/TreeConnector.js.map +7 -0
  161. package/dist/components/TrustDialog.js +2 -1
  162. package/dist/components/TrustDialog.js.map +2 -2
  163. package/dist/components/TurnCompletionIndicator.js +18 -0
  164. package/dist/components/TurnCompletionIndicator.js.map +7 -0
  165. package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
  166. package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
  167. package/dist/components/messages/AssistantTextMessage.js +20 -9
  168. package/dist/components/messages/AssistantTextMessage.js.map +2 -2
  169. package/dist/components/messages/AssistantThinkingMessage.js +18 -3
  170. package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
  171. package/dist/components/messages/AssistantToolUseMessage.js +17 -10
  172. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  173. package/dist/components/messages/GroupRenderer.js +54 -0
  174. package/dist/components/messages/GroupRenderer.js.map +7 -0
  175. package/dist/components/messages/NestedTasksPreview.js +24 -0
  176. package/dist/components/messages/NestedTasksPreview.js.map +7 -0
  177. package/dist/components/messages/ParallelTasksGroupView.js +93 -0
  178. package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
  179. package/dist/components/messages/TaskInModuleView.js +218 -0
  180. package/dist/components/messages/TaskInModuleView.js.map +7 -0
  181. package/dist/components/messages/TaskOutputContent.js +56 -0
  182. package/dist/components/messages/TaskOutputContent.js.map +7 -0
  183. package/dist/components/messages/UserPromptMessage.js +2 -2
  184. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  185. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
  186. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
  187. package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
  188. package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
  189. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
  190. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
  191. package/dist/constants/colors.js +120 -54
  192. package/dist/constants/colors.js.map +2 -2
  193. package/dist/constants/formatRules.js +102 -0
  194. package/dist/constants/formatRules.js.map +7 -0
  195. package/dist/constants/prompts.js +12 -34
  196. package/dist/constants/prompts.js.map +2 -2
  197. package/dist/constants/symbols.js +64 -6
  198. package/dist/constants/symbols.js.map +2 -2
  199. package/dist/constants/timing.js +5 -0
  200. package/dist/constants/timing.js.map +2 -2
  201. package/dist/constants/toolInputExamples.js +84 -0
  202. package/dist/constants/toolInputExamples.js.map +7 -0
  203. package/dist/core/backupManager.js +321 -0
  204. package/dist/core/backupManager.js.map +7 -0
  205. package/dist/core/config/defaults.js +84 -0
  206. package/dist/core/config/defaults.js.map +7 -0
  207. package/dist/core/config/index.js +111 -0
  208. package/dist/core/config/index.js.map +7 -0
  209. package/dist/core/config/loader.js +221 -0
  210. package/dist/core/config/loader.js.map +7 -0
  211. package/dist/core/config/migrations.js +128 -0
  212. package/dist/core/config/migrations.js.map +7 -0
  213. package/dist/core/config/schema.js +178 -0
  214. package/dist/core/config/schema.js.map +7 -0
  215. package/dist/core/costTracker.js +129 -0
  216. package/dist/core/costTracker.js.map +7 -0
  217. package/dist/core/gitAutoCommit.js +287 -0
  218. package/dist/core/gitAutoCommit.js.map +7 -0
  219. package/dist/core/index.js +8 -0
  220. package/dist/core/index.js.map +7 -0
  221. package/dist/core/operationTracker.js +212 -0
  222. package/dist/core/operationTracker.js.map +7 -0
  223. package/dist/core/permissions/auditLog.js +204 -0
  224. package/dist/core/permissions/auditLog.js.map +7 -0
  225. package/dist/core/permissions/engine/index.js +3 -0
  226. package/dist/core/permissions/engine/index.js.map +7 -0
  227. package/dist/core/permissions/engine/permissionEngine.js +106 -0
  228. package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
  229. package/dist/core/permissions/engine/types.js +1 -0
  230. package/dist/core/permissions/engine/types.js.map +7 -0
  231. package/dist/core/permissions/index.js +84 -0
  232. package/dist/core/permissions/index.js.map +7 -0
  233. package/dist/core/permissions/ruleEngine.js +259 -0
  234. package/dist/core/permissions/ruleEngine.js.map +7 -0
  235. package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
  236. package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
  237. package/dist/core/permissions/rules/autoEscalationRule.js +296 -0
  238. package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
  239. package/dist/core/permissions/rules/index.js +46 -0
  240. package/dist/core/permissions/rules/index.js.map +7 -0
  241. package/dist/core/permissions/rules/planModeRule.js +55 -0
  242. package/dist/core/permissions/rules/planModeRule.js.map +7 -0
  243. package/dist/core/permissions/rules/projectBoundaryRule.js +173 -0
  244. package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
  245. package/dist/core/permissions/rules/safeModeRule.js +65 -0
  246. package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
  247. package/dist/core/permissions/rules/sensitivePathsRule.js +345 -0
  248. package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
  249. package/dist/core/permissions/types.js +127 -0
  250. package/dist/core/permissions/types.js.map +7 -0
  251. package/dist/core/tokenStats.js +9 -0
  252. package/dist/core/tokenStats.js.map +7 -0
  253. package/dist/core/tokenStatsManager.js +331 -0
  254. package/dist/core/tokenStatsManager.js.map +7 -0
  255. package/dist/core/tools/executor.js +143 -0
  256. package/dist/core/tools/executor.js.map +7 -0
  257. package/dist/core/tools/index.js +15 -0
  258. package/dist/core/tools/index.js.map +7 -0
  259. package/dist/core/tools/registry.js +183 -0
  260. package/dist/core/tools/registry.js.map +7 -0
  261. package/dist/core/tools/types.js +1 -0
  262. package/dist/core/tools/types.js.map +7 -0
  263. package/dist/cost-tracker.js +23 -15
  264. package/dist/cost-tracker.js.map +2 -2
  265. package/dist/entrypoints/cli.js +158 -130
  266. package/dist/entrypoints/cli.js.map +2 -2
  267. package/dist/entrypoints/mcp.js +12 -4
  268. package/dist/entrypoints/mcp.js.map +2 -2
  269. package/dist/history.js +14 -3
  270. package/dist/history.js.map +2 -2
  271. package/dist/hooks/useAgentTokenStats.js +72 -0
  272. package/dist/hooks/useAgentTokenStats.js.map +7 -0
  273. package/dist/hooks/useAgentTranscripts.js +140 -0
  274. package/dist/hooks/useAgentTranscripts.js.map +7 -0
  275. package/dist/hooks/useAnimationSync.js +53 -0
  276. package/dist/hooks/useAnimationSync.js.map +7 -0
  277. package/dist/hooks/useArrowKeyHistory.js +4 -2
  278. package/dist/hooks/useArrowKeyHistory.js.map +2 -2
  279. package/dist/hooks/useCanUseTool.js +3 -1
  280. package/dist/hooks/useCanUseTool.js.map +2 -2
  281. package/dist/hooks/useExitOnCtrlCD.js +9 -5
  282. package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
  283. package/dist/hooks/useHookStatus.js +40 -0
  284. package/dist/hooks/useHookStatus.js.map +7 -0
  285. package/dist/hooks/useLogMessages.js +29 -2
  286. package/dist/hooks/useLogMessages.js.map +2 -2
  287. package/dist/hooks/useMessageGroups.js +43 -0
  288. package/dist/hooks/useMessageGroups.js.map +7 -0
  289. package/dist/hooks/useTerminalSize.js +62 -6
  290. package/dist/hooks/useTerminalSize.js.map +2 -2
  291. package/dist/hooks/useUnifiedCompletion.js +69 -0
  292. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  293. package/dist/i18n/index.js +109 -0
  294. package/dist/i18n/index.js.map +7 -0
  295. package/dist/i18n/locales/en.js +348 -0
  296. package/dist/i18n/locales/en.js.map +7 -0
  297. package/dist/i18n/locales/index.js +7 -0
  298. package/dist/i18n/locales/index.js.map +7 -0
  299. package/dist/i18n/locales/zh-CN.js +348 -0
  300. package/dist/i18n/locales/zh-CN.js.map +7 -0
  301. package/dist/i18n/types.js +8 -0
  302. package/dist/i18n/types.js.map +7 -0
  303. package/dist/permissions.js +28 -1
  304. package/dist/permissions.js.map +2 -2
  305. package/dist/query.js +253 -21
  306. package/dist/query.js.map +3 -3
  307. package/dist/screens/REPL.js +523 -194
  308. package/dist/screens/REPL.js.map +3 -3
  309. package/dist/services/adapters/chatCompletions.js +3 -1
  310. package/dist/services/adapters/chatCompletions.js.map +2 -2
  311. package/dist/services/adapters/messageNormalizer.js +354 -0
  312. package/dist/services/adapters/messageNormalizer.js.map +7 -0
  313. package/dist/services/adapters/responsesAPI.js +6 -3
  314. package/dist/services/adapters/responsesAPI.js.map +2 -2
  315. package/dist/services/checkpointManager.js +386 -0
  316. package/dist/services/checkpointManager.js.map +7 -0
  317. package/dist/services/claude.js +192 -14
  318. package/dist/services/claude.js.map +3 -3
  319. package/dist/services/compressionService.js +50 -1
  320. package/dist/services/compressionService.js.map +2 -2
  321. package/dist/services/contextMonitor.js +162 -0
  322. package/dist/services/contextMonitor.js.map +7 -0
  323. package/dist/services/customCommands.js +60 -41
  324. package/dist/services/customCommands.js.map +2 -2
  325. package/dist/services/hookExecutor.js +173 -1
  326. package/dist/services/hookExecutor.js.map +2 -2
  327. package/dist/services/intelligentCompactor.js +281 -0
  328. package/dist/services/intelligentCompactor.js.map +7 -0
  329. package/dist/services/lspConfig.js +109 -0
  330. package/dist/services/lspConfig.js.map +7 -0
  331. package/dist/services/mcpClient.js +338 -43
  332. package/dist/services/mcpClient.js.map +2 -2
  333. package/dist/services/modelOrchestrator.js +310 -0
  334. package/dist/services/modelOrchestrator.js.map +7 -0
  335. package/dist/services/openai.js +8 -1
  336. package/dist/services/openai.js.map +2 -2
  337. package/dist/services/outputStyles.js +138 -0
  338. package/dist/services/outputStyles.js.map +7 -0
  339. package/dist/services/plugins/index.js +5 -0
  340. package/dist/services/plugins/index.js.map +7 -0
  341. package/dist/services/plugins/lspServers.js +188 -0
  342. package/dist/services/plugins/lspServers.js.map +7 -0
  343. package/dist/services/plugins/pluginRuntime.js +229 -0
  344. package/dist/services/plugins/pluginRuntime.js.map +7 -0
  345. package/dist/services/plugins/pluginValidation.js +219 -0
  346. package/dist/services/plugins/pluginValidation.js.map +7 -0
  347. package/dist/services/plugins/skillMarketplace.js +556 -0
  348. package/dist/services/plugins/skillMarketplace.js.map +7 -0
  349. package/dist/services/responseStateManager.js +37 -3
  350. package/dist/services/responseStateManager.js.map +2 -2
  351. package/dist/services/sandbox/filesystemBoundary.js +341 -0
  352. package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
  353. package/dist/services/sandbox/index.js +14 -0
  354. package/dist/services/sandbox/index.js.map +7 -0
  355. package/dist/services/sandbox/networkProxy.js +293 -0
  356. package/dist/services/sandbox/networkProxy.js.map +7 -0
  357. package/dist/services/sandbox/sandboxController.js +574 -0
  358. package/dist/services/sandbox/sandboxController.js.map +7 -0
  359. package/dist/services/sandbox/types.js +50 -0
  360. package/dist/services/sandbox/types.js.map +7 -0
  361. package/dist/services/sessionMemory.js +266 -0
  362. package/dist/services/sessionMemory.js.map +7 -0
  363. package/dist/services/taskRouter.js +324 -0
  364. package/dist/services/taskRouter.js.map +7 -0
  365. package/dist/tools/ArchitectTool/ArchitectTool.js +7 -1
  366. package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
  367. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +6 -2
  368. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  369. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +2 -1
  370. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
  371. package/dist/tools/BaseTool.js +72 -0
  372. package/dist/tools/BaseTool.js.map +7 -0
  373. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
  374. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
  375. package/dist/tools/BashTool/BashTool.js +79 -3
  376. package/dist/tools/BashTool/BashTool.js.map +2 -2
  377. package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
  378. package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
  379. package/dist/tools/BashTool/OutputLine.js +54 -0
  380. package/dist/tools/BashTool/OutputLine.js.map +2 -2
  381. package/dist/tools/BashTool/prompt.js +336 -3
  382. package/dist/tools/BashTool/prompt.js.map +2 -2
  383. package/dist/tools/FileEditTool/FileEditTool.js +29 -4
  384. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  385. package/dist/tools/FileEditTool/prompt.js +6 -3
  386. package/dist/tools/FileEditTool/prompt.js.map +2 -2
  387. package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
  388. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  389. package/dist/tools/FileWriteTool/prompt.js +4 -2
  390. package/dist/tools/FileWriteTool/prompt.js.map +2 -2
  391. package/dist/tools/GlobTool/GlobTool.js +4 -2
  392. package/dist/tools/GlobTool/GlobTool.js.map +2 -2
  393. package/dist/tools/GrepTool/GrepTool.js +36 -7
  394. package/dist/tools/GrepTool/GrepTool.js.map +2 -2
  395. package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
  396. package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
  397. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
  398. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
  399. package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
  400. package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
  401. package/dist/tools/LspTool/LspTool.js +664 -0
  402. package/dist/tools/LspTool/LspTool.js.map +7 -0
  403. package/dist/tools/LspTool/prompt.js +27 -0
  404. package/dist/tools/LspTool/prompt.js.map +7 -0
  405. package/dist/tools/MCPTool/MCPTool.js +9 -1
  406. package/dist/tools/MCPTool/MCPTool.js.map +2 -2
  407. package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
  408. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  409. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
  410. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  411. package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
  412. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  413. package/dist/tools/MultiEditTool/prompt.js +5 -3
  414. package/dist/tools/MultiEditTool/prompt.js.map +2 -2
  415. package/dist/tools/NotebookEditTool/NotebookEditTool.js +7 -2
  416. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  417. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
  418. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +75 -0
  419. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
  420. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +109 -0
  421. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
  422. package/dist/tools/PlanModeTool/prompt.js +94 -0
  423. package/dist/tools/PlanModeTool/prompt.js.map +7 -0
  424. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
  425. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
  426. package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
  427. package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
  428. package/dist/tools/SkillTool/SkillTool.js +10 -4
  429. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  430. package/dist/tools/SkillTool/prompt.js +1 -1
  431. package/dist/tools/SkillTool/prompt.js.map +1 -1
  432. package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
  433. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
  434. package/dist/tools/SlashCommandTool/prompt.js +35 -0
  435. package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
  436. package/dist/tools/TaskOutputTool/TaskOutputTool.js +190 -0
  437. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
  438. package/dist/tools/TaskOutputTool/prompt.js +15 -0
  439. package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
  440. package/dist/tools/TaskTool/TaskTool.js +310 -104
  441. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  442. package/dist/tools/TaskTool/prompt.js.map +2 -2
  443. package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -77
  444. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
  445. package/dist/tools/URLFetcherTool/URLFetcherTool.js +4 -1
  446. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
  447. package/dist/tools/URLFetcherTool/cache.js +55 -8
  448. package/dist/tools/URLFetcherTool/cache.js.map +2 -2
  449. package/dist/tools.js +31 -2
  450. package/dist/tools.js.map +2 -2
  451. package/dist/types/hooks.js +4 -0
  452. package/dist/types/hooks.js.map +2 -2
  453. package/dist/types/marketplace.js.map +2 -2
  454. package/dist/types/messageGroup.js +36 -0
  455. package/dist/types/messageGroup.js.map +7 -0
  456. package/dist/types/plugin.js.map +2 -2
  457. package/dist/types/thinking.js +1 -0
  458. package/dist/types/thinking.js.map +7 -0
  459. package/dist/utils/BackgroundShellManager.js +136 -39
  460. package/dist/utils/BackgroundShellManager.js.map +2 -2
  461. package/dist/utils/CircuitBreaker.js +242 -0
  462. package/dist/utils/CircuitBreaker.js.map +7 -0
  463. package/dist/utils/MessageBatchBuffer.js +102 -0
  464. package/dist/utils/MessageBatchBuffer.js.map +7 -0
  465. package/dist/utils/PersistentShell.js +151 -1
  466. package/dist/utils/PersistentShell.js.map +2 -2
  467. package/dist/utils/agentLoader.js +1 -23
  468. package/dist/utils/agentLoader.js.map +2 -2
  469. package/dist/utils/agentTranscripts.js +641 -0
  470. package/dist/utils/agentTranscripts.js.map +7 -0
  471. package/dist/utils/animationManager.js +213 -0
  472. package/dist/utils/animationManager.js.map +7 -0
  473. package/dist/utils/animationSync.js +110 -0
  474. package/dist/utils/animationSync.js.map +7 -0
  475. package/dist/utils/ask.js +2 -0
  476. package/dist/utils/ask.js.map +2 -2
  477. package/dist/utils/asyncFile.js +215 -0
  478. package/dist/utils/asyncFile.js.map +7 -0
  479. package/dist/utils/backgroundAgentManager.js +231 -0
  480. package/dist/utils/backgroundAgentManager.js.map +7 -0
  481. package/dist/utils/config.js +108 -10
  482. package/dist/utils/config.js.map +2 -2
  483. package/dist/utils/conversationRecovery.js +19 -0
  484. package/dist/utils/conversationRecovery.js.map +2 -2
  485. package/dist/utils/credentials/CredentialStore.js +1 -0
  486. package/dist/utils/credentials/CredentialStore.js.map +7 -0
  487. package/dist/utils/credentials/EncryptedFileStore.js +157 -0
  488. package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
  489. package/dist/utils/credentials/index.js +37 -0
  490. package/dist/utils/credentials/index.js.map +7 -0
  491. package/dist/utils/credentials/migration.js +82 -0
  492. package/dist/utils/credentials/migration.js.map +7 -0
  493. package/dist/utils/exit.js +73 -0
  494. package/dist/utils/exit.js.map +7 -0
  495. package/dist/utils/format.js +73 -5
  496. package/dist/utils/format.js.map +2 -2
  497. package/dist/utils/generators.js +76 -6
  498. package/dist/utils/generators.js.map +2 -2
  499. package/dist/utils/globalErrorHandler.js +149 -0
  500. package/dist/utils/globalErrorHandler.js.map +7 -0
  501. package/dist/utils/groupHandlers/index.js +8 -0
  502. package/dist/utils/groupHandlers/index.js.map +7 -0
  503. package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
  504. package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
  505. package/dist/utils/groupHandlers/taskHandler.js +104 -0
  506. package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
  507. package/dist/utils/groupHandlers/types.js +1 -0
  508. package/dist/utils/groupHandlers/types.js.map +7 -0
  509. package/dist/utils/logRotation.js +224 -0
  510. package/dist/utils/logRotation.js.map +7 -0
  511. package/dist/utils/markdown.js +13 -1
  512. package/dist/utils/markdown.js.map +2 -2
  513. package/dist/utils/marketplaceManager.js +3 -5
  514. package/dist/utils/marketplaceManager.js.map +2 -2
  515. package/dist/utils/memSafety.js +264 -0
  516. package/dist/utils/memSafety.js.map +7 -0
  517. package/dist/utils/messageGroupManager.js +274 -0
  518. package/dist/utils/messageGroupManager.js.map +7 -0
  519. package/dist/utils/messages.js +13 -4
  520. package/dist/utils/messages.js.map +2 -2
  521. package/dist/utils/model.js +119 -15
  522. package/dist/utils/model.js.map +3 -3
  523. package/dist/utils/permissions/filesystem.js +162 -6
  524. package/dist/utils/permissions/filesystem.js.map +2 -2
  525. package/dist/utils/plan/planMode.js +143 -0
  526. package/dist/utils/plan/planMode.js.map +7 -0
  527. package/dist/utils/pluginLoader.js +17 -21
  528. package/dist/utils/pluginLoader.js.map +2 -2
  529. package/dist/utils/ripgrep.js +55 -2
  530. package/dist/utils/ripgrep.js.map +2 -2
  531. package/dist/utils/safePath.js +132 -0
  532. package/dist/utils/safePath.js.map +7 -0
  533. package/dist/utils/sanitizeInput.js +32 -0
  534. package/dist/utils/sanitizeInput.js.map +7 -0
  535. package/dist/utils/secureKeyStorage.js +312 -0
  536. package/dist/utils/secureKeyStorage.js.map +7 -0
  537. package/dist/utils/sensitiveFiles.js +125 -0
  538. package/dist/utils/sensitiveFiles.js.map +7 -0
  539. package/dist/utils/session/sessionPlugins.js +67 -0
  540. package/dist/utils/session/sessionPlugins.js.map +7 -0
  541. package/dist/utils/taskDisplayUtils.js +257 -0
  542. package/dist/utils/taskDisplayUtils.js.map +7 -0
  543. package/dist/utils/teamConfig.js +2 -1
  544. package/dist/utils/teamConfig.js.map +2 -2
  545. package/dist/utils/theme.js +6 -6
  546. package/dist/utils/theme.js.map +1 -1
  547. package/dist/utils/todoStorage.js +92 -2
  548. package/dist/utils/todoStorage.js.map +2 -2
  549. package/dist/utils/toolRiskClassification.js +207 -0
  550. package/dist/utils/toolRiskClassification.js.map +7 -0
  551. package/dist/utils/toolTimeout.js +136 -0
  552. package/dist/utils/toolTimeout.js.map +7 -0
  553. package/dist/utils/tooling/safeRender.js +116 -0
  554. package/dist/utils/tooling/safeRender.js.map +7 -0
  555. package/dist/utils/userFriendlyError.js +346 -0
  556. package/dist/utils/userFriendlyError.js.map +7 -0
  557. package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
  558. package/dist/version.js +2 -2
  559. package/dist/version.js.map +1 -1
  560. package/package.json +17 -5
  561. package/scripts/postinstall.js +128 -38
  562. package/dist/commands/agents.js +0 -2086
  563. package/dist/commands/agents.js.map +0 -7
  564. package/dist/commands/build.js +0 -74
  565. package/dist/commands/build.js.map +0 -7
  566. package/dist/commands/compression.js +0 -57
  567. package/dist/commands/compression.js.map +0 -7
  568. package/dist/commands/listen.js +0 -37
  569. package/dist/commands/listen.js.map +0 -7
  570. package/dist/commands/login.js +0 -37
  571. package/dist/commands/login.js.map +0 -7
  572. package/dist/commands/logout.js +0 -33
  573. package/dist/commands/logout.js.map +0 -7
  574. package/dist/commands/mcp.js +0 -40
  575. package/dist/commands/mcp.js.map +0 -7
  576. package/dist/commands/mcp_refresh.js +0 -40
  577. package/dist/commands/mcp_refresh.js.map +0 -7
  578. package/dist/commands/modelstatus.js +0 -21
  579. package/dist/commands/modelstatus.js.map +0 -7
  580. package/dist/commands/onboarding.js +0 -36
  581. package/dist/commands/onboarding.js.map +0 -7
  582. package/dist/commands/plugin-interactive.js +0 -446
  583. package/dist/commands/plugin-interactive.js.map +0 -7
  584. package/dist/commands/pr_comments.js +0 -61
  585. package/dist/commands/pr_comments.js.map +0 -7
  586. package/dist/commands/release-notes.js +0 -30
  587. package/dist/commands/release-notes.js.map +0 -7
  588. package/dist/commands/review.js +0 -51
  589. package/dist/commands/review.js.map +0 -7
  590. package/dist/components/Bug.js +0 -147
  591. package/dist/components/Bug.js.map +0 -7
  592. package/dist/components/ModelSelector.js +0 -2062
  593. package/dist/components/ModelSelector.js.map +0 -7
  594. package/dist/components/ModelStatusDisplay.js +0 -87
  595. package/dist/components/ModelStatusDisplay.js.map +0 -7
  596. package/dist/entrypoints/cli-wrapper.js +0 -61
  597. package/dist/entrypoints/cli-wrapper.js.map +0 -7
  598. package/dist/hooks/useCancelRequest.js +0 -28
  599. package/dist/hooks/useCancelRequest.js.map +0 -7
  600. package/dist/screens/Doctor.js +0 -22
  601. package/dist/screens/Doctor.js.map +0 -7
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/toolRiskClassification.ts"],
4
+ "sourcesContent": ["/**\n * Tool Risk Classification System\n *\n * Classifies tools into three risk levels for the Smart Safety Mode:\n * - safe: Read-only operations, no side effects\n * - monitored: Has side effects but reversible/low risk\n * - dangerous: Potentially destructive, requires confirmation\n */\n\nexport type RiskLevel = 'safe' | 'monitored' | 'dangerous'\n\n/**\n * Default risk levels for each tool type\n */\nexport const TOOL_RISK_LEVELS: Record<string, RiskLevel> = {\n // \uD83D\uDFE2 Safe layer: Read-only, no side effects\n Read: 'safe',\n Glob: 'safe',\n Grep: 'safe',\n LS: 'safe',\n WebSearch: 'safe',\n WebFetch: 'safe',\n Think: 'safe',\n AskUserQuestion: 'safe',\n MemoryRead: 'safe',\n NotebookRead: 'safe',\n TaskOutput: 'safe',\n EnterPlanMode: 'safe',\n ExitPlanMode: 'safe',\n TaskList: 'safe',\n TaskGet: 'safe',\n Skill: 'safe',\n\n // \uD83D\uDFE1 Monitored layer: Has side effects but reversible/low risk\n Edit: 'monitored',\n Write: 'monitored',\n NotebookEdit: 'monitored',\n MemoryWrite: 'monitored',\n TodoWrite: 'monitored',\n Task: 'monitored',\n TaskCreate: 'monitored',\n TaskUpdate: 'monitored',\n TaskStop: 'monitored',\n\n // \uD83D\uDD34 Dangerous layer: Requires confirmation (Bash handled separately)\n Bash: 'dangerous',\n MCPTool: 'dangerous',\n}\n\n/**\n * Safe Bash command patterns - automatically allowed even in Smart/Strict mode\n * These patterns match common development commands that are low-risk\n */\nexport const SAFE_BASH_PATTERNS: RegExp[] = [\n // Git - all common operations\n /^git\\s+(status|diff|log|branch|show|remote|fetch|pull|push|commit|add|checkout|merge|rebase|stash|tag|clone|init|config|rev-parse|symbolic-ref)/i,\n\n // File viewing (read-only)\n /^ls(\\s|$)/i,\n /^cat\\s/i,\n /^head\\s/i,\n /^tail\\s/i,\n /^pwd$/i,\n /^echo\\s/i,\n /^which\\s/i,\n /^tree(\\s|$)/i,\n /^date$/i,\n /^whoami$/i,\n /^find\\s/i,\n /^wc\\s/i,\n /^grep\\s/i,\n /^rg\\s/i,\n /^less\\s/i,\n /^more\\s/i,\n /^file\\s/i,\n /^stat\\s/i,\n /^du\\s/i,\n /^df\\s/i,\n\n // Package managers - common development operations\n /^npm\\s+(install|i|ci|run|test|start|build|list|ls|outdated|view|info|init|publish|pack|version|audit|dedupe)/i,\n /^npx\\s/i,\n /^bun\\s+(install|i|add|remove|run|test|build|pm|create|init|link|unlink|update|outdated)/i,\n /^bunx\\s/i,\n /^yarn\\s+(install|add|remove|run|test|build|init|create|link|unlink|upgrade|outdated)/i,\n /^pnpm\\s+(install|i|add|remove|run|test|build|init|create|link|unlink|update|outdated)/i,\n /^pip\\s+(install|list|show|freeze|check)/i,\n /^pip3\\s+(install|list|show|freeze|check)/i,\n /^poetry\\s+(install|add|remove|run|build|init|check|show)/i,\n /^cargo\\s+(build|run|test|check|clippy|fmt|doc|bench|new|init|add|remove)/i,\n /^go\\s+(build|run|test|get|mod|fmt|vet|generate)/i,\n /^composer\\s+(install|require|remove|update|dump-autoload)/i,\n /^gem\\s+(install|list|update)/i,\n /^bundle\\s+(install|exec|update)/i,\n\n // Version queries\n /^(node|npm|bun|yarn|pnpm|python|python3|pip|pip3|cargo|rustc|go|java|ruby|php)\\s+(--version|-v|-V)$/i,\n /^(node|npm|bun|yarn|pnpm|python|python3|pip|pip3|cargo|rustc|go|java|ruby|php)\\s+-version$/i,\n\n // Build and test tools\n /^make(\\s|$)/i,\n /^cmake\\s/i,\n /^ninja(\\s|$)/i,\n /^pytest(\\s|$)/i,\n /^jest(\\s|$)/i,\n /^vitest(\\s|$)/i,\n /^mocha(\\s|$)/i,\n /^ava(\\s|$)/i,\n /^tape(\\s|$)/i,\n /^tap(\\s|$)/i,\n /^tsc(\\s|$)/i,\n /^eslint(\\s|$)/i,\n /^prettier(\\s|$)/i,\n /^biome(\\s|$)/i,\n\n // Docker (read-only and common operations)\n /^docker\\s+(ps|images|logs|inspect|version|info|stats|top|port|diff)/i,\n /^docker\\s+(build|run|exec|pull|push|start|stop|restart)/i,\n /^docker-compose\\s+(ps|logs|config|up|down|build|pull|restart)/i,\n\n // Kubernetes (read-only)\n /^kubectl\\s+(get|describe|logs|explain|version|config|cluster-info)/i,\n\n // Environment and shell\n /^env$/i,\n /^printenv/i,\n /^export\\s/i,\n /^source\\s/i,\n /^\\.\\s/i,\n\n // Process viewing\n /^ps(\\s|$)/i,\n /^top$/i,\n /^htop$/i,\n\n // Network diagnostics (read-only)\n /^ping\\s/i,\n /^traceroute\\s/i,\n /^dig\\s/i,\n /^nslookup\\s/i,\n /^host\\s/i,\n /^ifconfig$/i,\n /^ip\\s+(addr|link|route)/i,\n\n // Archive viewing\n /^tar\\s+(-t|--list)/i,\n /^unzip\\s+-l/i,\n /^zipinfo\\s/i,\n\n // Text processing\n /^sort(\\s|$)/i,\n /^uniq(\\s|$)/i,\n /^cut(\\s|$)/i,\n /^awk\\s/i,\n /^sed\\s/i,\n /^tr\\s/i,\n /^diff\\s/i,\n /^md5sum\\s/i,\n /^sha256sum\\s/i,\n\n // Directory operations (safe)\n /^mkdir\\s/i,\n /^touch\\s/i,\n /^cp\\s/i,\n /^mv\\s/i,\n]\n\n/**\n * Dangerous Bash command patterns - always require confirmation\n * These patterns match potentially destructive commands\n */\nexport const DANGEROUS_BASH_PATTERNS: RegExp[] = [\n // File deletion\n /\\brm\\s/i,\n /\\brmdir\\s/i,\n /\\bunlink\\s/i,\n\n // Privilege escalation\n /\\bsudo\\s/i,\n /\\bsu\\s/i,\n /\\bdoas\\s/i,\n /\\bpkexec\\s/i,\n\n // Permission changes\n /\\bchmod\\s/i,\n /\\bchown\\s/i,\n /\\bchgrp\\s/i,\n\n // Disk operations\n /\\bmkfs\\b/i,\n /\\bfdisk\\s/i,\n /\\bparted\\s/i,\n /\\bdd\\s+if=/i,\n /\\bshred\\s/i,\n\n // System control\n /\\bsystemctl\\s/i,\n /\\bservice\\s/i,\n /\\breboot\\b/i,\n /\\bshutdown\\s/i,\n /\\bhalt\\b/i,\n /\\bpoweroff\\b/i,\n\n // Dangerous redirections\n />\\s*\\/(?!tmp|dev\\/null)/i, // Redirect to root paths (except /tmp and /dev/null)\n />\\s*~\\//i, // Redirect to home directory paths\n\n // Shell execution from network\n /\\|\\s*(bash|sh|zsh|fish)/i,\n /curl.*\\|\\s*(bash|sh)/i,\n /wget.*\\|\\s*(bash|sh)/i,\n\n // Environment destruction\n /\\bkillall\\s/i,\n /\\bpkill\\s/i,\n /kill\\s+-9/i,\n\n // Network dangerous\n /\\bnc\\s+-l/i, // netcat listen mode\n /\\biptables\\s/i,\n /\\bufw\\s/i,\n\n // Crontab\n /\\bcrontab\\s+-r/i,\n\n // Git destructive\n /\\bgit\\s+(reset\\s+--hard|clean\\s+-f|push\\s+--force|push\\s+-f)/i,\n]\n\n/**\n * Classify a Bash command into a risk level\n *\n * @param command The bash command to classify\n * @returns The risk level of the command\n */\nexport function classifyBashCommand(command: string): RiskLevel {\n // Trim and normalize whitespace\n const normalizedCommand = command.trim().replace(/\\s+/g, ' ')\n\n // Check dangerous patterns first (higher priority)\n if (DANGEROUS_BASH_PATTERNS.some(p => p.test(normalizedCommand))) {\n return 'dangerous'\n }\n\n // Check safe patterns\n if (SAFE_BASH_PATTERNS.some(p => p.test(normalizedCommand))) {\n return 'safe'\n }\n\n // Default to monitored (allows in Smart mode, asks in Strict mode)\n return 'monitored'\n}\n\n/**\n * Get the risk level for a tool\n *\n * @param toolName The name of the tool\n * @param input Optional tool input for command-specific classification\n * @returns The risk level of the tool\n */\nexport function getToolRiskLevel(\n toolName: string,\n input?: { command?: string },\n): RiskLevel {\n // Special handling for Bash commands\n if (toolName === 'Bash' && input?.command) {\n return classifyBashCommand(input.command)\n }\n\n // Look up in the static table\n return TOOL_RISK_LEVELS[toolName] ?? 'dangerous'\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,136 @@
1
+ const TOOL_TIMEOUTS = {
2
+ /** Quick read-only operations (file read, grep, glob) */
3
+ FAST: 3e4,
4
+ // 30 seconds
5
+ /** Standard operations (most tools) */
6
+ STANDARD: 12e4,
7
+ // 2 minutes
8
+ /** Long-running operations (bash commands, web fetch) */
9
+ LONG: 6e5,
10
+ // 10 minutes
11
+ /** Extended operations (task agents, complex builds) */
12
+ EXTENDED: 18e5,
13
+ // 30 minutes
14
+ /** No timeout (special cases only) */
15
+ NONE: 0
16
+ };
17
+ const TOOL_TIMEOUT_CONFIG = {
18
+ // Fast operations (30s)
19
+ Read: TOOL_TIMEOUTS.FAST,
20
+ View: TOOL_TIMEOUTS.FAST,
21
+ Grep: TOOL_TIMEOUTS.FAST,
22
+ Glob: TOOL_TIMEOUTS.FAST,
23
+ LS: TOOL_TIMEOUTS.FAST,
24
+ LSP: TOOL_TIMEOUTS.FAST,
25
+ // Standard operations (2min)
26
+ Write: TOOL_TIMEOUTS.STANDARD,
27
+ Edit: TOOL_TIMEOUTS.STANDARD,
28
+ MultiEdit: TOOL_TIMEOUTS.STANDARD,
29
+ NotebookEdit: TOOL_TIMEOUTS.STANDARD,
30
+ TodoWrite: TOOL_TIMEOUTS.STANDARD,
31
+ TodoRead: TOOL_TIMEOUTS.STANDARD,
32
+ MemoryRead: TOOL_TIMEOUTS.STANDARD,
33
+ MemoryWrite: TOOL_TIMEOUTS.STANDARD,
34
+ AskUser: TOOL_TIMEOUTS.STANDARD,
35
+ Think: TOOL_TIMEOUTS.STANDARD,
36
+ // Long operations (10min)
37
+ Bash: TOOL_TIMEOUTS.LONG,
38
+ WebFetch: TOOL_TIMEOUTS.LONG,
39
+ WebSearch: TOOL_TIMEOUTS.LONG,
40
+ mcp__: TOOL_TIMEOUTS.LONG,
41
+ // MCP tools prefix
42
+ // Extended operations (30min)
43
+ Task: TOOL_TIMEOUTS.EXTENDED
44
+ };
45
+ function getToolTimeout(toolName) {
46
+ if (toolName in TOOL_TIMEOUT_CONFIG) {
47
+ return TOOL_TIMEOUT_CONFIG[toolName];
48
+ }
49
+ for (const [prefix, timeout] of Object.entries(TOOL_TIMEOUT_CONFIG)) {
50
+ if (prefix.endsWith("__") && toolName.startsWith(prefix)) {
51
+ return timeout;
52
+ }
53
+ }
54
+ return TOOL_TIMEOUTS.STANDARD;
55
+ }
56
+ class ToolTimeoutError extends Error {
57
+ toolName;
58
+ timeoutMs;
59
+ constructor(toolName, timeoutMs) {
60
+ super(
61
+ `Tool '${toolName}' execution timed out after ${Math.round(timeoutMs / 1e3)} seconds`
62
+ );
63
+ this.name = "ToolTimeoutError";
64
+ this.toolName = toolName;
65
+ this.timeoutMs = timeoutMs;
66
+ }
67
+ }
68
+ async function* withTimeout(generator, toolName, timeoutMs) {
69
+ const actualTimeout = timeoutMs ?? getToolTimeout(toolName);
70
+ if (actualTimeout === 0) {
71
+ yield* generator;
72
+ return;
73
+ }
74
+ let timeoutId = null;
75
+ let hasTimedOut = false;
76
+ const timeoutPromise = new Promise((_, reject) => {
77
+ timeoutId = setTimeout(() => {
78
+ hasTimedOut = true;
79
+ reject(new ToolTimeoutError(toolName, actualTimeout));
80
+ }, actualTimeout);
81
+ });
82
+ try {
83
+ while (true) {
84
+ const result = await Promise.race([generator.next(), timeoutPromise]);
85
+ if (result.done) {
86
+ return;
87
+ }
88
+ yield result.value;
89
+ }
90
+ } finally {
91
+ if (timeoutId !== null) {
92
+ clearTimeout(timeoutId);
93
+ }
94
+ if (hasTimedOut) {
95
+ try {
96
+ await generator.return(void 0);
97
+ } catch {
98
+ }
99
+ }
100
+ }
101
+ }
102
+ async function withPromiseTimeout(promise, toolName, timeoutMs) {
103
+ const actualTimeout = timeoutMs ?? getToolTimeout(toolName);
104
+ if (actualTimeout === 0) {
105
+ return promise;
106
+ }
107
+ let timeoutId = null;
108
+ const timeoutPromise = new Promise((_, reject) => {
109
+ timeoutId = setTimeout(() => {
110
+ reject(new ToolTimeoutError(toolName, actualTimeout));
111
+ }, actualTimeout);
112
+ });
113
+ try {
114
+ return await Promise.race([promise, timeoutPromise]);
115
+ } finally {
116
+ if (timeoutId !== null) {
117
+ clearTimeout(timeoutId);
118
+ }
119
+ }
120
+ }
121
+ function formatTimeout(timeoutMs) {
122
+ if (timeoutMs === 0) return "no limit";
123
+ if (timeoutMs < 6e4) return `${Math.round(timeoutMs / 1e3)}s`;
124
+ if (timeoutMs < 36e5) return `${Math.round(timeoutMs / 6e4)}min`;
125
+ return `${Math.round(timeoutMs / 36e5)}hr`;
126
+ }
127
+ export {
128
+ TOOL_TIMEOUTS,
129
+ TOOL_TIMEOUT_CONFIG,
130
+ ToolTimeoutError,
131
+ formatTimeout,
132
+ getToolTimeout,
133
+ withPromiseTimeout,
134
+ withTimeout
135
+ };
136
+ //# sourceMappingURL=toolTimeout.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/toolTimeout.ts"],
4
+ "sourcesContent": ["/**\n * Tool Execution Timeout Utility\n *\n * Provides timeout handling for tool execution to prevent infinite hangs.\n * Each tool can have a different timeout based on its nature.\n */\n\n/**\n * Default timeout values for different tool categories (in milliseconds)\n */\nexport const TOOL_TIMEOUTS = {\n /** Quick read-only operations (file read, grep, glob) */\n FAST: 30_000, // 30 seconds\n\n /** Standard operations (most tools) */\n STANDARD: 120_000, // 2 minutes\n\n /** Long-running operations (bash commands, web fetch) */\n LONG: 600_000, // 10 minutes\n\n /** Extended operations (task agents, complex builds) */\n EXTENDED: 1_800_000, // 30 minutes\n\n /** No timeout (special cases only) */\n NONE: 0,\n} as const\n\n/**\n * Tool-specific timeout configurations\n * Maps tool names to their timeout duration\n */\nexport const TOOL_TIMEOUT_CONFIG: Record<string, number> = {\n // Fast operations (30s)\n Read: TOOL_TIMEOUTS.FAST,\n View: TOOL_TIMEOUTS.FAST,\n Grep: TOOL_TIMEOUTS.FAST,\n Glob: TOOL_TIMEOUTS.FAST,\n LS: TOOL_TIMEOUTS.FAST,\n LSP: TOOL_TIMEOUTS.FAST,\n\n // Standard operations (2min)\n Write: TOOL_TIMEOUTS.STANDARD,\n Edit: TOOL_TIMEOUTS.STANDARD,\n MultiEdit: TOOL_TIMEOUTS.STANDARD,\n NotebookEdit: TOOL_TIMEOUTS.STANDARD,\n TodoWrite: TOOL_TIMEOUTS.STANDARD,\n TodoRead: TOOL_TIMEOUTS.STANDARD,\n MemoryRead: TOOL_TIMEOUTS.STANDARD,\n MemoryWrite: TOOL_TIMEOUTS.STANDARD,\n AskUser: TOOL_TIMEOUTS.STANDARD,\n Think: TOOL_TIMEOUTS.STANDARD,\n\n // Long operations (10min)\n Bash: TOOL_TIMEOUTS.LONG,\n WebFetch: TOOL_TIMEOUTS.LONG,\n WebSearch: TOOL_TIMEOUTS.LONG,\n mcp__: TOOL_TIMEOUTS.LONG, // MCP tools prefix\n\n // Extended operations (30min)\n Task: TOOL_TIMEOUTS.EXTENDED,\n}\n\n/**\n * Get timeout duration for a specific tool\n */\nexport function getToolTimeout(toolName: string): number {\n // Check for exact match first\n if (toolName in TOOL_TIMEOUT_CONFIG) {\n return TOOL_TIMEOUT_CONFIG[toolName]\n }\n\n // Check for prefix matches (e.g., mcp__ tools)\n for (const [prefix, timeout] of Object.entries(TOOL_TIMEOUT_CONFIG)) {\n if (prefix.endsWith('__') && toolName.startsWith(prefix)) {\n return timeout\n }\n }\n\n // Default to standard timeout\n return TOOL_TIMEOUTS.STANDARD\n}\n\n/**\n * Error thrown when tool execution times out\n */\nexport class ToolTimeoutError extends Error {\n public readonly toolName: string\n public readonly timeoutMs: number\n\n constructor(toolName: string, timeoutMs: number) {\n super(\n `Tool '${toolName}' execution timed out after ${Math.round(timeoutMs / 1000)} seconds`,\n )\n this.name = 'ToolTimeoutError'\n this.toolName = toolName\n this.timeoutMs = timeoutMs\n }\n}\n\n/**\n * Wraps an async generator with a timeout\n * Yields values as they come, but throws ToolTimeoutError if the overall\n * execution exceeds the timeout.\n */\nexport async function* withTimeout<T>(\n generator: AsyncGenerator<T, void>,\n toolName: string,\n timeoutMs?: number,\n): AsyncGenerator<T, void> {\n const actualTimeout = timeoutMs ?? getToolTimeout(toolName)\n\n // No timeout\n if (actualTimeout === 0) {\n yield* generator\n return\n }\n\n // Create a timeout promise\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n let hasTimedOut = false\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n hasTimedOut = true\n reject(new ToolTimeoutError(toolName, actualTimeout))\n }, actualTimeout)\n })\n\n try {\n while (true) {\n // Race between the next value and timeout\n const result = await Promise.race([generator.next(), timeoutPromise])\n\n if (result.done) {\n return\n }\n\n yield result.value as T\n }\n } finally {\n // Clean up timeout\n if (timeoutId !== null) {\n clearTimeout(timeoutId)\n }\n\n // If we timed out, try to return/cleanup the generator\n if (hasTimedOut) {\n try {\n await generator.return(undefined)\n } catch {\n // Ignore cleanup errors\n }\n }\n }\n}\n\n/**\n * Wraps a promise with a timeout\n * Useful for non-generator async operations\n */\nexport async function withPromiseTimeout<T>(\n promise: Promise<T>,\n toolName: string,\n timeoutMs?: number,\n): Promise<T> {\n const actualTimeout = timeoutMs ?? getToolTimeout(toolName)\n\n // No timeout\n if (actualTimeout === 0) {\n return promise\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new ToolTimeoutError(toolName, actualTimeout))\n }, actualTimeout)\n })\n\n try {\n return await Promise.race([promise, timeoutPromise])\n } finally {\n if (timeoutId !== null) {\n clearTimeout(timeoutId)\n }\n }\n}\n\n/**\n * Format timeout for display\n */\nexport function formatTimeout(timeoutMs: number): string {\n if (timeoutMs === 0) return 'no limit'\n if (timeoutMs < 60_000) return `${Math.round(timeoutMs / 1000)}s`\n if (timeoutMs < 3_600_000) return `${Math.round(timeoutMs / 60_000)}min`\n return `${Math.round(timeoutMs / 3_600_000)}hr`\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,116 @@
1
+ import * as React from "react";
2
+ import { Box, Text } from "ink";
3
+ import { SEMANTIC_COLORS } from "../../constants/colors.js";
4
+ function DefaultToolResult({
5
+ output
6
+ }) {
7
+ let displayContent;
8
+ if (output === null || output === void 0) {
9
+ displayContent = "(no output)";
10
+ } else if (typeof output === "string") {
11
+ displayContent = output.length > 500 ? output.slice(0, 500) + "..." : output;
12
+ } else if (typeof output === "object") {
13
+ try {
14
+ const json = JSON.stringify(output, null, 2);
15
+ displayContent = json.length > 500 ? json.slice(0, 500) + "..." : json;
16
+ } catch {
17
+ displayContent = "[Object - cannot stringify]";
18
+ }
19
+ } else {
20
+ displayContent = String(output);
21
+ }
22
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, displayContent));
23
+ }
24
+ function ErrorToolResult({
25
+ error,
26
+ toolName
27
+ }) {
28
+ const errorMessage = error instanceof Error ? error.message : String(error || "Unknown error");
29
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, toolName ? `[${toolName}] ` : "", "Error rendering result:"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, errorMessage));
30
+ }
31
+ function safeRenderToolResult(tool, output, options) {
32
+ if (!tool) {
33
+ return /* @__PURE__ */ React.createElement(DefaultToolResult, { output });
34
+ }
35
+ if (!tool.renderToolResultMessage) {
36
+ return /* @__PURE__ */ React.createElement(DefaultToolResult, { output });
37
+ }
38
+ try {
39
+ const rendered = tool.renderToolResultMessage(output, options);
40
+ if (rendered === null || rendered === void 0) {
41
+ return /* @__PURE__ */ React.createElement(DefaultToolResult, { output });
42
+ }
43
+ return rendered;
44
+ } catch (error) {
45
+ return /* @__PURE__ */ React.createElement(ErrorToolResult, { error, toolName: tool.name });
46
+ }
47
+ }
48
+ function safeRenderToolUseMessage(tool, input, options) {
49
+ if (!tool) {
50
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Unknown tool call"));
51
+ }
52
+ if (!tool.renderToolUseMessage) {
53
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: "cyan" }, tool.name), options.verbose && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", JSON.stringify(input).slice(0, 100))));
54
+ }
55
+ try {
56
+ const rendered = tool.renderToolUseMessage(input, options);
57
+ if (rendered === null || rendered === void 0) {
58
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "cyan" }, tool.name));
59
+ }
60
+ return rendered;
61
+ } catch (error) {
62
+ return /* @__PURE__ */ React.createElement(ErrorToolResult, { error, toolName: tool.name });
63
+ }
64
+ }
65
+ function safeRenderToolRejectedMessage(tool, ...args) {
66
+ if (!tool || !tool.renderToolUseRejectedMessage) {
67
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "Tool use rejected"));
68
+ }
69
+ try {
70
+ const rendered = tool.renderToolUseRejectedMessage(...args);
71
+ if (rendered === null || rendered === void 0) {
72
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, tool.name, " rejected"));
73
+ }
74
+ return rendered;
75
+ } catch (error) {
76
+ return /* @__PURE__ */ React.createElement(ErrorToolResult, { error, toolName: tool.name });
77
+ }
78
+ }
79
+ function isValidReactNode(value) {
80
+ if (value === null || value === void 0) {
81
+ return true;
82
+ }
83
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
84
+ return true;
85
+ }
86
+ if (Array.isArray(value)) {
87
+ return value.every(isValidReactNode);
88
+ }
89
+ if (typeof value === "object" && value !== null) {
90
+ return "$$typeof" in value || React.isValidElement(value);
91
+ }
92
+ return false;
93
+ }
94
+ function wrapRenderFunction(renderFn, fallback) {
95
+ return (...args) => {
96
+ try {
97
+ const result = renderFn(...args);
98
+ if (result === null || result === void 0) {
99
+ return fallback;
100
+ }
101
+ return result;
102
+ } catch {
103
+ return fallback;
104
+ }
105
+ };
106
+ }
107
+ export {
108
+ DefaultToolResult,
109
+ ErrorToolResult,
110
+ isValidReactNode,
111
+ safeRenderToolRejectedMessage,
112
+ safeRenderToolResult,
113
+ safeRenderToolUseMessage,
114
+ wrapRenderFunction
115
+ };
116
+ //# sourceMappingURL=safeRender.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/utils/tooling/safeRender.tsx"],
4
+ "sourcesContent": ["/**\n * Safe Rendering Utilities for Tool Results\n *\n * Provides null-safe wrappers for tool rendering methods to prevent\n * crashes from undefined returns or exceptions.\n *\n * Part of Phase 1.3: Null Guards Completion\n */\n\nimport * as React from 'react'\nimport { Box, Text } from 'ink'\nimport { Tool } from '@tool'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\n/**\n * Default tool result component when tool doesn't provide a renderer.\n */\nexport function DefaultToolResult({\n output,\n}: {\n output: unknown\n}): React.ReactElement {\n let displayContent: string\n\n if (output === null || output === undefined) {\n displayContent = '(no output)'\n } else if (typeof output === 'string') {\n displayContent = output.length > 500 ? output.slice(0, 500) + '...' : output\n } else if (typeof output === 'object') {\n try {\n const json = JSON.stringify(output, null, 2)\n displayContent = json.length > 500 ? json.slice(0, 500) + '...' : json\n } catch {\n displayContent = '[Object - cannot stringify]'\n }\n } else {\n displayContent = String(output)\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text color={SEMANTIC_COLORS.dim}>{displayContent}</Text>\n </Box>\n )\n}\n\n/**\n * Error display component for tool rendering failures.\n */\nexport function ErrorToolResult({\n error,\n toolName,\n}: {\n error: unknown\n toolName?: string\n}): React.ReactElement {\n const errorMessage =\n error instanceof Error ? error.message : String(error || 'Unknown error')\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"red\">\n {toolName ? `[${toolName}] ` : ''}Error rendering result:\n </Text>\n <Text color={SEMANTIC_COLORS.dim}>{errorMessage}</Text>\n </Box>\n )\n}\n\n/**\n * Safely render a tool result with comprehensive error handling.\n *\n * @param tool - The tool that produced the result\n * @param output - The tool's output data\n * @param options - Rendering options\n * @returns A React node that is guaranteed to be renderable\n */\nexport function safeRenderToolResult(\n tool: Tool | undefined | null,\n output: unknown,\n options: { verbose: boolean },\n): React.ReactNode {\n // No tool provided\n if (!tool) {\n return <DefaultToolResult output={output} />\n }\n\n // Tool doesn't have a renderer\n if (!tool.renderToolResultMessage) {\n return <DefaultToolResult output={output} />\n }\n\n try {\n const rendered = tool.renderToolResultMessage(output, options)\n\n // Handle null/undefined returns\n if (rendered === null || rendered === undefined) {\n return <DefaultToolResult output={output} />\n }\n\n return rendered\n } catch (error) {\n // Catch any rendering errors\n return <ErrorToolResult error={error} toolName={tool.name} />\n }\n}\n\n/**\n * Safely render a tool use message with comprehensive error handling.\n *\n * @param tool - The tool being used\n * @param input - The tool's input parameters\n * @param options - Rendering options\n * @returns A React node that is guaranteed to be renderable\n */\nexport function safeRenderToolUseMessage(\n tool: Tool | undefined | null,\n input: unknown,\n options: { verbose: boolean },\n): React.ReactNode {\n // No tool provided\n if (!tool) {\n return (\n <Box>\n <Text color={SEMANTIC_COLORS.dim}>Unknown tool call</Text>\n </Box>\n )\n }\n\n // Tool doesn't have a renderer\n if (!tool.renderToolUseMessage) {\n return (\n <Box>\n <Text>\n <Text color=\"cyan\">{tool.name}</Text>\n {options.verbose && (\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n {JSON.stringify(input).slice(0, 100)}\n </Text>\n )}\n </Text>\n </Box>\n )\n }\n\n try {\n const rendered = tool.renderToolUseMessage(input, options)\n\n // Handle null/undefined returns\n if (rendered === null || rendered === undefined) {\n return (\n <Box>\n <Text color=\"cyan\">{tool.name}</Text>\n </Box>\n )\n }\n\n return rendered\n } catch (error) {\n return <ErrorToolResult error={error} toolName={tool.name} />\n }\n}\n\n/**\n * Safely render a tool rejection message with comprehensive error handling.\n *\n * @param tool - The tool that was rejected\n * @param args - Arguments to pass to the rejection renderer\n * @returns A React node that is guaranteed to be renderable\n */\nexport function safeRenderToolRejectedMessage(\n tool: Tool | undefined | null,\n ...args: unknown[]\n): React.ReactNode {\n // No tool or no renderer\n if (!tool || !tool.renderToolUseRejectedMessage) {\n return (\n <Box>\n <Text color=\"yellow\">Tool use rejected</Text>\n </Box>\n )\n }\n\n try {\n const rendered = tool.renderToolUseRejectedMessage(...args)\n\n // Handle null/undefined returns\n if (rendered === null || rendered === undefined) {\n return (\n <Box>\n <Text color=\"yellow\">{tool.name} rejected</Text>\n </Box>\n )\n }\n\n return rendered\n } catch (error) {\n return <ErrorToolResult error={error} toolName={tool.name} />\n }\n}\n\n/**\n * Type guard to check if a value is a valid React node.\n */\nexport function isValidReactNode(value: unknown): value is React.ReactNode {\n if (value === null || value === undefined) {\n return true // React accepts null/undefined\n }\n\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return true\n }\n\n if (Array.isArray(value)) {\n return value.every(isValidReactNode)\n }\n\n // Check for React element\n if (typeof value === 'object' && value !== null) {\n return '$$typeof' in value || React.isValidElement(value)\n }\n\n return false\n}\n\n/**\n * Wrap a potentially unsafe render function with error boundaries.\n *\n * @param renderFn - The render function to wrap\n * @param fallback - Fallback content on error\n * @returns A safe render function\n */\nexport function wrapRenderFunction<TArgs extends unknown[]>(\n renderFn: (...args: TArgs) => React.ReactNode,\n fallback: React.ReactNode,\n): (...args: TArgs) => React.ReactNode {\n return (...args: TArgs) => {\n try {\n const result = renderFn(...args)\n if (result === null || result === undefined) {\n return fallback\n }\n return result\n } catch {\n return fallback\n }\n }\n}\n"],
5
+ "mappings": "AASA,YAAY,WAAW;AACvB,SAAS,KAAK,YAAY;AAE1B,SAAS,uBAAuB;AAKzB,SAAS,kBAAkB;AAAA,EAChC;AACF,GAEuB;AACrB,MAAI;AAEJ,MAAI,WAAW,QAAQ,WAAW,QAAW;AAC3C,qBAAiB;AAAA,EACnB,WAAW,OAAO,WAAW,UAAU;AACrC,qBAAiB,OAAO,SAAS,MAAM,OAAO,MAAM,GAAG,GAAG,IAAI,QAAQ;AAAA,EACxE,WAAW,OAAO,WAAW,UAAU;AACrC,QAAI;AACF,YAAM,OAAO,KAAK,UAAU,QAAQ,MAAM,CAAC;AAC3C,uBAAiB,KAAK,SAAS,MAAM,KAAK,MAAM,GAAG,GAAG,IAAI,QAAQ;AAAA,IACpE,QAAQ;AACN,uBAAiB;AAAA,IACnB;AAAA,EACF,OAAO;AACL,qBAAiB,OAAO,MAAM;AAAA,EAChC;AAEA,SACE,oCAAC,OAAI,eAAc,YACjB,oCAAC,QAAK,OAAO,gBAAgB,OAAM,cAAe,CACpD;AAEJ;AAKO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AACF,GAGuB;AACrB,QAAM,eACJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,SAAS,eAAe;AAE1E,SACE,oCAAC,OAAI,eAAc,YACjB,oCAAC,QAAK,OAAM,SACT,WAAW,IAAI,QAAQ,OAAO,IAAG,yBACpC,GACA,oCAAC,QAAK,OAAO,gBAAgB,OAAM,YAAa,CAClD;AAEJ;AAUO,SAAS,qBACd,MACA,QACA,SACiB;AAEjB,MAAI,CAAC,MAAM;AACT,WAAO,oCAAC,qBAAkB,QAAgB;AAAA,EAC5C;AAGA,MAAI,CAAC,KAAK,yBAAyB;AACjC,WAAO,oCAAC,qBAAkB,QAAgB;AAAA,EAC5C;AAEA,MAAI;AACF,UAAM,WAAW,KAAK,wBAAwB,QAAQ,OAAO;AAG7D,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC/C,aAAO,oCAAC,qBAAkB,QAAgB;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,WAAO,oCAAC,mBAAgB,OAAc,UAAU,KAAK,MAAM;AAAA,EAC7D;AACF;AAUO,SAAS,yBACd,MACA,OACA,SACiB;AAEjB,MAAI,CAAC,MAAM;AACT,WACE,oCAAC,WACC,oCAAC,QAAK,OAAO,gBAAgB,OAAK,mBAAiB,CACrD;AAAA,EAEJ;AAGA,MAAI,CAAC,KAAK,sBAAsB;AAC9B,WACE,oCAAC,WACC,oCAAC,YACC,oCAAC,QAAK,OAAM,UAAQ,KAAK,IAAK,GAC7B,QAAQ,WACP,oCAAC,QAAK,OAAO,gBAAgB,OAC1B,KACA,KAAK,UAAU,KAAK,EAAE,MAAM,GAAG,GAAG,CACrC,CAEJ,CACF;AAAA,EAEJ;AAEA,MAAI;AACF,UAAM,WAAW,KAAK,qBAAqB,OAAO,OAAO;AAGzD,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC/C,aACE,oCAAC,WACC,oCAAC,QAAK,OAAM,UAAQ,KAAK,IAAK,CAChC;AAAA,IAEJ;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,oCAAC,mBAAgB,OAAc,UAAU,KAAK,MAAM;AAAA,EAC7D;AACF;AASO,SAAS,8BACd,SACG,MACc;AAEjB,MAAI,CAAC,QAAQ,CAAC,KAAK,8BAA8B;AAC/C,WACE,oCAAC,WACC,oCAAC,QAAK,OAAM,YAAS,mBAAiB,CACxC;AAAA,EAEJ;AAEA,MAAI;AACF,UAAM,WAAW,KAAK,6BAA6B,GAAG,IAAI;AAG1D,QAAI,aAAa,QAAQ,aAAa,QAAW;AAC/C,aACE,oCAAC,WACC,oCAAC,QAAK,OAAM,YAAU,KAAK,MAAK,WAAS,CAC3C;AAAA,IAEJ;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,oCAAC,mBAAgB,OAAc,UAAU,KAAK,MAAM;AAAA,EAC7D;AACF;AAKO,SAAS,iBAAiB,OAA0C;AACzE,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO;AAAA,EACT;AAEA,MACE,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,WACjB;AACA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,MAAM,gBAAgB;AAAA,EACrC;AAGA,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO,cAAc,SAAS,MAAM,eAAe,KAAK;AAAA,EAC1D;AAEA,SAAO;AACT;AASO,SAAS,mBACd,UACA,UACqC;AACrC,SAAO,IAAI,SAAgB;AACzB,QAAI;AACF,YAAM,SAAS,SAAS,GAAG,IAAI;AAC/B,UAAI,WAAW,QAAQ,WAAW,QAAW;AAC3C,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,346 @@
1
+ import { randomUUID } from "crypto";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import { t, tSafe } from "../i18n/index.js";
5
+ var ErrorCategory = /* @__PURE__ */ ((ErrorCategory2) => {
6
+ ErrorCategory2["NETWORK_CONNECTION"] = "network_connection";
7
+ ErrorCategory2["NETWORK_TIMEOUT"] = "network_timeout";
8
+ ErrorCategory2["NETWORK_DNS"] = "network_dns";
9
+ ErrorCategory2["API_RATE_LIMIT"] = "api_rate_limit";
10
+ ErrorCategory2["API_AUTH"] = "api_auth";
11
+ ErrorCategory2["API_QUOTA"] = "api_quota";
12
+ ErrorCategory2["API_SERVER_ERROR"] = "api_server_error";
13
+ ErrorCategory2["API_INVALID_RESPONSE"] = "api_invalid_response";
14
+ ErrorCategory2["FILE_NOT_FOUND"] = "file_not_found";
15
+ ErrorCategory2["FILE_PERMISSION"] = "file_permission";
16
+ ErrorCategory2["FILE_TOO_LARGE"] = "file_too_large";
17
+ ErrorCategory2["FILE_ENCODING"] = "file_encoding";
18
+ ErrorCategory2["CONFIG_MISSING"] = "config_missing";
19
+ ErrorCategory2["CONFIG_INVALID"] = "config_invalid";
20
+ ErrorCategory2["CONFIG_API_KEY"] = "config_api_key";
21
+ ErrorCategory2["MODEL_UNAVAILABLE"] = "model_unavailable";
22
+ ErrorCategory2["MODEL_CONTEXT_LENGTH"] = "model_context_length";
23
+ ErrorCategory2["MODEL_CONTENT_FILTER"] = "model_content_filter";
24
+ ErrorCategory2["SYSTEM_MEMORY"] = "system_memory";
25
+ ErrorCategory2["SYSTEM_PROCESS"] = "system_process";
26
+ ErrorCategory2["UNKNOWN"] = "unknown";
27
+ return ErrorCategory2;
28
+ })(ErrorCategory || {});
29
+ const CATEGORY_TO_I18N_PREFIX = {
30
+ ["network_connection" /* NETWORK_CONNECTION */]: "friendlyError.networkConnection",
31
+ ["network_timeout" /* NETWORK_TIMEOUT */]: "friendlyError.networkTimeout",
32
+ ["network_dns" /* NETWORK_DNS */]: "friendlyError.networkDns",
33
+ ["api_rate_limit" /* API_RATE_LIMIT */]: "friendlyError.apiRateLimit",
34
+ ["api_auth" /* API_AUTH */]: "friendlyError.apiAuth",
35
+ ["api_quota" /* API_QUOTA */]: "friendlyError.apiQuota",
36
+ ["api_server_error" /* API_SERVER_ERROR */]: "friendlyError.apiServerError",
37
+ ["api_invalid_response" /* API_INVALID_RESPONSE */]: "friendlyError.apiInvalidResponse",
38
+ ["file_not_found" /* FILE_NOT_FOUND */]: "friendlyError.fileNotFound",
39
+ ["file_permission" /* FILE_PERMISSION */]: "friendlyError.filePermission",
40
+ ["file_too_large" /* FILE_TOO_LARGE */]: "friendlyError.fileTooLarge",
41
+ ["file_encoding" /* FILE_ENCODING */]: "friendlyError.fileEncoding",
42
+ ["config_missing" /* CONFIG_MISSING */]: "friendlyError.configMissing",
43
+ ["config_invalid" /* CONFIG_INVALID */]: "friendlyError.configInvalid",
44
+ ["config_api_key" /* CONFIG_API_KEY */]: "friendlyError.configApiKey",
45
+ ["model_unavailable" /* MODEL_UNAVAILABLE */]: "friendlyError.modelUnavailable",
46
+ ["model_context_length" /* MODEL_CONTEXT_LENGTH */]: "friendlyError.modelContextLength",
47
+ ["model_content_filter" /* MODEL_CONTENT_FILTER */]: "friendlyError.modelContentFilter",
48
+ ["system_memory" /* SYSTEM_MEMORY */]: "friendlyError.systemMemory",
49
+ ["system_process" /* SYSTEM_PROCESS */]: "friendlyError.systemProcess",
50
+ ["unknown" /* UNKNOWN */]: "friendlyError.unknown"
51
+ };
52
+ function getFriendlyMessage(category) {
53
+ const prefix = CATEGORY_TO_I18N_PREFIX[category];
54
+ const suggestions = [];
55
+ for (let i = 1; i <= 3; i++) {
56
+ const suggestion = tSafe(`${prefix}.suggestion${i}`);
57
+ if (suggestion) {
58
+ suggestions.push(suggestion);
59
+ }
60
+ }
61
+ return {
62
+ title: tSafe(`${prefix}.title`) || category,
63
+ description: tSafe(`${prefix}.description`) || "",
64
+ suggestions
65
+ };
66
+ }
67
+ const FRIENDLY_MESSAGES = Object.fromEntries(
68
+ Object.values(ErrorCategory).map((category) => [
69
+ category,
70
+ getFriendlyMessage(category)
71
+ ])
72
+ );
73
+ const ERROR_PATTERNS = [
74
+ // Network errors
75
+ {
76
+ category: "network_connection" /* NETWORK_CONNECTION */,
77
+ patterns: [
78
+ "socket.*closed",
79
+ "ECONNREFUSED",
80
+ "ECONNRESET",
81
+ "ENOTFOUND",
82
+ "connection.*refused",
83
+ "connection.*closed",
84
+ "network.*error",
85
+ "fetch failed"
86
+ ]
87
+ },
88
+ {
89
+ category: "network_timeout" /* NETWORK_TIMEOUT */,
90
+ patterns: [
91
+ "timeout",
92
+ "ETIMEDOUT",
93
+ "timed out",
94
+ "deadline exceeded",
95
+ "request.*timeout"
96
+ ]
97
+ },
98
+ {
99
+ category: "network_dns" /* NETWORK_DNS */,
100
+ patterns: ["ENOTFOUND", "getaddrinfo", "DNS", "resolve.*failed"]
101
+ },
102
+ // API errors
103
+ {
104
+ category: "api_rate_limit" /* API_RATE_LIMIT */,
105
+ patterns: ["rate.*limit", "429", "too many requests", "quota.*exceeded"]
106
+ },
107
+ {
108
+ category: "api_auth" /* API_AUTH */,
109
+ patterns: [
110
+ "401",
111
+ "unauthorized",
112
+ "authentication.*failed",
113
+ "invalid.*key",
114
+ "api.*key.*invalid"
115
+ ]
116
+ },
117
+ {
118
+ category: "api_quota" /* API_QUOTA */,
119
+ patterns: [
120
+ "insufficient.*quota",
121
+ "billing",
122
+ "credit",
123
+ "exceeded.*quota",
124
+ "402"
125
+ ]
126
+ },
127
+ {
128
+ category: "api_server_error" /* API_SERVER_ERROR */,
129
+ patterns: ["500", "502", "503", "504", "internal.*error", "server.*error"]
130
+ },
131
+ // File errors
132
+ {
133
+ category: "file_not_found" /* FILE_NOT_FOUND */,
134
+ patterns: ["ENOENT", "no such file", "file.*not.*found", "does not exist"]
135
+ },
136
+ {
137
+ category: "file_permission" /* FILE_PERMISSION */,
138
+ patterns: ["EACCES", "EPERM", "permission.*denied", "access.*denied"]
139
+ },
140
+ {
141
+ category: "file_too_large" /* FILE_TOO_LARGE */,
142
+ patterns: ["file.*too.*large", "EFBIG", "size.*limit"]
143
+ },
144
+ // Model errors
145
+ {
146
+ category: "model_context_length" /* MODEL_CONTEXT_LENGTH */,
147
+ patterns: [
148
+ "context.*length",
149
+ "token.*limit",
150
+ "max.*tokens",
151
+ "too.*long",
152
+ "exceeds.*maximum"
153
+ ]
154
+ },
155
+ {
156
+ category: "model_content_filter" /* MODEL_CONTENT_FILTER */,
157
+ patterns: ["content.*filter", "safety", "blocked", "moderation"]
158
+ },
159
+ {
160
+ category: "model_unavailable" /* MODEL_UNAVAILABLE */,
161
+ patterns: ["model.*not.*found", "model.*unavailable", "does not exist"]
162
+ },
163
+ // Config errors
164
+ {
165
+ category: "config_api_key" /* CONFIG_API_KEY */,
166
+ patterns: [
167
+ "api.*key.*not.*set",
168
+ "missing.*api.*key",
169
+ "ANTHROPIC_API_KEY",
170
+ "OPENAI_API_KEY"
171
+ ]
172
+ },
173
+ // System errors
174
+ {
175
+ category: "system_memory" /* SYSTEM_MEMORY */,
176
+ patterns: ["ENOMEM", "out of memory", "heap", "memory.*limit"]
177
+ }
178
+ ];
179
+ function classifyError(error) {
180
+ const errorString = getErrorString(error).toLowerCase();
181
+ for (const { category, patterns } of ERROR_PATTERNS) {
182
+ for (const pattern of patterns) {
183
+ if (typeof pattern === "string") {
184
+ if (errorString.includes(pattern.toLowerCase())) {
185
+ return category;
186
+ }
187
+ } else if (pattern.test(errorString)) {
188
+ return category;
189
+ }
190
+ }
191
+ }
192
+ return "unknown" /* UNKNOWN */;
193
+ }
194
+ function getErrorString(error) {
195
+ if (error instanceof Error) {
196
+ return `${error.name}: ${error.message} ${error.stack || ""}`;
197
+ }
198
+ return String(error);
199
+ }
200
+ class UserFriendlyError extends Error {
201
+ id;
202
+ category;
203
+ friendlyMessage;
204
+ originalError;
205
+ context;
206
+ timestamp;
207
+ constructor(originalError, context = {}, categoryOverride) {
208
+ const category = categoryOverride || classifyError(originalError);
209
+ const friendly = FRIENDLY_MESSAGES[category];
210
+ super(friendly.title);
211
+ this.name = "UserFriendlyError";
212
+ this.id = randomUUID().slice(0, 8);
213
+ this.category = category;
214
+ this.friendlyMessage = friendly;
215
+ this.originalError = originalError;
216
+ this.context = context;
217
+ this.timestamp = /* @__PURE__ */ new Date();
218
+ if (originalError instanceof Error && originalError.stack) {
219
+ this.stack = originalError.stack;
220
+ }
221
+ }
222
+ /**
223
+ * Get user-facing display message
224
+ */
225
+ getUserMessage() {
226
+ const message = getFriendlyMessage(this.category);
227
+ const suggestionLabel = t("friendlyError.suggestionLabel");
228
+ const errorIdLabel = t("friendlyError.errorIdLabel");
229
+ const lines = [
230
+ `\u26A0\uFE0F ${message.title}`,
231
+ "",
232
+ message.description,
233
+ "",
234
+ `\u{1F4A1} ${suggestionLabel}:`,
235
+ ...message.suggestions.map((s) => ` \u2022 ${s}`),
236
+ "",
237
+ `\u{1F4CB} ${errorIdLabel}: ${this.id}`
238
+ ];
239
+ return lines.join("\n");
240
+ }
241
+ /**
242
+ * Get technical message for developers
243
+ */
244
+ getTechnicalMessage() {
245
+ const original = this.originalError instanceof Error ? this.originalError.message : String(this.originalError);
246
+ return `[${this.category}] ${original}`;
247
+ }
248
+ /**
249
+ * Create structured log entry
250
+ */
251
+ toLogEntry() {
252
+ return {
253
+ id: this.id,
254
+ timestamp: this.timestamp.toISOString(),
255
+ category: this.category,
256
+ friendlyTitle: this.friendlyMessage.title,
257
+ technicalMessage: this.getTechnicalMessage(),
258
+ stack: this.stack,
259
+ context: this.context,
260
+ systemInfo: {
261
+ platform: process.platform,
262
+ nodeVersion: process.version,
263
+ mintoVersion: getMintoVersion()
264
+ }
265
+ };
266
+ }
267
+ }
268
+ let errorLogPath = null;
269
+ function getErrorLogPath() {
270
+ if (!errorLogPath) {
271
+ const logDir = path.join(process.env.HOME || "", ".minto", "logs");
272
+ errorLogPath = path.join(logDir, "errors.jsonl");
273
+ }
274
+ return errorLogPath;
275
+ }
276
+ function logUserFriendlyError(error) {
277
+ try {
278
+ const logPath = getErrorLogPath();
279
+ const logDir = path.dirname(logPath);
280
+ if (!fs.existsSync(logDir)) {
281
+ fs.mkdirSync(logDir, { recursive: true });
282
+ }
283
+ const entry = error.toLogEntry();
284
+ fs.appendFileSync(logPath, JSON.stringify(entry) + "\n");
285
+ } catch {
286
+ }
287
+ }
288
+ function getRecentErrors(limit = 10) {
289
+ try {
290
+ const logPath = getErrorLogPath();
291
+ if (!fs.existsSync(logPath)) {
292
+ return [];
293
+ }
294
+ const content = fs.readFileSync(logPath, "utf-8");
295
+ const lines = content.trim().split("\n").filter(Boolean);
296
+ const entries = lines.slice(-limit).map((line) => {
297
+ try {
298
+ return JSON.parse(line);
299
+ } catch {
300
+ return null;
301
+ }
302
+ }).filter((e) => e !== null);
303
+ return entries.reverse();
304
+ } catch {
305
+ return [];
306
+ }
307
+ }
308
+ function getMintoVersion() {
309
+ try {
310
+ const packageJsonPath = path.join(__dirname, "../../package.json");
311
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
312
+ return packageJson.version || "unknown";
313
+ } catch {
314
+ return "unknown";
315
+ }
316
+ }
317
+ function toUserFriendlyError(error, context) {
318
+ if (error instanceof UserFriendlyError) {
319
+ return error;
320
+ }
321
+ return new UserFriendlyError(error, context);
322
+ }
323
+ function formatErrorForUser(error, options = {}) {
324
+ const friendly = toUserFriendlyError(error, options.context);
325
+ logUserFriendlyError(friendly);
326
+ let message = friendly.getUserMessage();
327
+ if (options.showTechnical) {
328
+ const technicalLabel = t("friendlyError.technicalDetailsLabel");
329
+ message += `
330
+
331
+ \u{1F527} ${technicalLabel}: ${friendly.getTechnicalMessage()}`;
332
+ }
333
+ return message;
334
+ }
335
+ export {
336
+ ERROR_PATTERNS,
337
+ ErrorCategory,
338
+ FRIENDLY_MESSAGES,
339
+ UserFriendlyError,
340
+ classifyError,
341
+ formatErrorForUser,
342
+ getRecentErrors,
343
+ logUserFriendlyError,
344
+ toUserFriendlyError
345
+ };
346
+ //# sourceMappingURL=userFriendlyError.js.map