@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,102 @@
1
+ class MessageBatchBuffer {
2
+ buffer = [];
3
+ flushTimer = null;
4
+ flushCallback;
5
+ options;
6
+ messageCount = 0;
7
+ flushCount = 0;
8
+ constructor(flushCallback, options = {}) {
9
+ this.flushCallback = flushCallback;
10
+ this.options = {
11
+ flushInterval: options.flushInterval ?? 100,
12
+ maxBatchSize: options.maxBatchSize ?? 50,
13
+ debug: options.debug ?? false
14
+ };
15
+ }
16
+ /**
17
+ * Add a message to the buffer
18
+ * Will trigger immediate flush if buffer size exceeds maxBatchSize
19
+ */
20
+ add(message) {
21
+ this.buffer.push(message);
22
+ this.messageCount++;
23
+ if (this.options.debug) {
24
+ console.log(
25
+ `[MessageBatchBuffer] Added message (buffer: ${this.buffer.length}/${this.options.maxBatchSize})`
26
+ );
27
+ }
28
+ if (this.buffer.length >= this.options.maxBatchSize) {
29
+ if (this.options.debug) {
30
+ console.log(`[MessageBatchBuffer] Buffer full, forcing immediate flush`);
31
+ }
32
+ this.flush();
33
+ return;
34
+ }
35
+ this.scheduleFlush();
36
+ }
37
+ /**
38
+ * Schedule a flush after flushInterval
39
+ * Cancels any pending flush and reschedules
40
+ */
41
+ scheduleFlush() {
42
+ if (this.flushTimer !== null) {
43
+ clearTimeout(this.flushTimer);
44
+ }
45
+ this.flushTimer = setTimeout(() => {
46
+ this.flush();
47
+ }, this.options.flushInterval);
48
+ }
49
+ /**
50
+ * Immediately flush all buffered messages
51
+ */
52
+ flush() {
53
+ if (this.buffer.length === 0) {
54
+ return;
55
+ }
56
+ const messagesToFlush = [...this.buffer];
57
+ this.buffer = [];
58
+ this.flushCount++;
59
+ if (this.flushTimer !== null) {
60
+ clearTimeout(this.flushTimer);
61
+ this.flushTimer = null;
62
+ }
63
+ if (this.options.debug) {
64
+ console.log(
65
+ `[MessageBatchBuffer] Flush #${this.flushCount}: ${messagesToFlush.length} messages`
66
+ );
67
+ }
68
+ this.flushCallback(messagesToFlush);
69
+ }
70
+ /**
71
+ * Clean up timers and discard remaining messages
72
+ *
73
+ * CRITICAL: Does NOT flush to avoid race condition with exit flow
74
+ * When component unmounts, we're likely exiting and don't want to
75
+ * trigger additional renders that would clear the cost summary.
76
+ *
77
+ * Any pending messages will be discarded on unmount, which is acceptable
78
+ * since we're exiting anyway.
79
+ */
80
+ dispose() {
81
+ if (this.flushTimer !== null) {
82
+ clearTimeout(this.flushTimer);
83
+ this.flushTimer = null;
84
+ }
85
+ this.buffer = [];
86
+ }
87
+ /**
88
+ * Get statistics about buffer performance
89
+ */
90
+ getStats() {
91
+ return {
92
+ totalMessages: this.messageCount,
93
+ totalFlushes: this.flushCount,
94
+ averageBatchSize: this.flushCount > 0 ? this.messageCount / this.flushCount : 0,
95
+ currentBufferSize: this.buffer.length
96
+ };
97
+ }
98
+ }
99
+ export {
100
+ MessageBatchBuffer
101
+ };
102
+ //# sourceMappingURL=MessageBatchBuffer.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/MessageBatchBuffer.ts"],
4
+ "sourcesContent": ["/**\n * MessageBatchBuffer - Unified message batching system to eliminate screen flicker\n *\n * Problem: Each streaming message triggers immediate React state update \u2192 render \u2192 flicker\n * Solution: Buffer messages and flush in batches at controlled intervals\n *\n * Benefits:\n * - Reduces render frequency by batching multiple messages into single update\n * - Eliminates visual flicker from rapid successive renders\n * - Balances responsiveness with performance\n *\n * @example\n * const buffer = new MessageBatchBuffer((messages) => {\n * setMessages(prev => [...prev, ...messages])\n * }, { flushInterval: 100 })\n *\n * // Instead of: setMessages(prev => [...prev, message])\n * buffer.add(message)\n */\n\nimport type { Message } from '@minto-types/conversation'\n\nexport interface MessageBatchBufferOptions {\n /**\n * How often to flush buffered messages (ms)\n * @default 100 - balances responsiveness with batching efficiency\n */\n flushInterval?: number\n\n /**\n * Maximum messages to buffer before forcing a flush\n * Prevents unbounded memory growth\n * @default 50\n */\n maxBatchSize?: number\n\n /**\n * Enable debug logging\n * @default false\n */\n debug?: boolean\n}\n\nexport class MessageBatchBuffer {\n private buffer: Message[] = []\n private flushTimer: NodeJS.Timeout | null = null\n private readonly flushCallback: (messages: Message[]) => void\n private readonly options: Required<MessageBatchBufferOptions>\n private messageCount = 0\n private flushCount = 0\n\n constructor(\n flushCallback: (messages: Message[]) => void,\n options: MessageBatchBufferOptions = {},\n ) {\n this.flushCallback = flushCallback\n this.options = {\n flushInterval: options.flushInterval ?? 100,\n maxBatchSize: options.maxBatchSize ?? 50,\n debug: options.debug ?? false,\n }\n }\n\n /**\n * Add a message to the buffer\n * Will trigger immediate flush if buffer size exceeds maxBatchSize\n */\n add(message: Message): void {\n this.buffer.push(message)\n this.messageCount++\n\n if (this.options.debug) {\n console.log(\n `[MessageBatchBuffer] Added message (buffer: ${this.buffer.length}/${this.options.maxBatchSize})`,\n )\n }\n\n // Force flush if buffer is full\n if (this.buffer.length >= this.options.maxBatchSize) {\n if (this.options.debug) {\n console.log(`[MessageBatchBuffer] Buffer full, forcing immediate flush`)\n }\n this.flush()\n return\n }\n\n // Schedule deferred flush\n this.scheduleFlush()\n }\n\n /**\n * Schedule a flush after flushInterval\n * Cancels any pending flush and reschedules\n */\n private scheduleFlush(): void {\n // Clear any existing timer\n if (this.flushTimer !== null) {\n clearTimeout(this.flushTimer)\n }\n\n // Schedule new flush\n this.flushTimer = setTimeout(() => {\n this.flush()\n }, this.options.flushInterval)\n }\n\n /**\n * Immediately flush all buffered messages\n */\n flush(): void {\n if (this.buffer.length === 0) {\n return\n }\n\n const messagesToFlush = [...this.buffer]\n this.buffer = []\n this.flushCount++\n\n if (this.flushTimer !== null) {\n clearTimeout(this.flushTimer)\n this.flushTimer = null\n }\n\n if (this.options.debug) {\n console.log(\n `[MessageBatchBuffer] Flush #${this.flushCount}: ${messagesToFlush.length} messages`,\n )\n }\n\n this.flushCallback(messagesToFlush)\n }\n\n /**\n * Clean up timers and discard remaining messages\n *\n * CRITICAL: Does NOT flush to avoid race condition with exit flow\n * When component unmounts, we're likely exiting and don't want to\n * trigger additional renders that would clear the cost summary.\n *\n * Any pending messages will be discarded on unmount, which is acceptable\n * since we're exiting anyway.\n */\n dispose(): void {\n // Clear timer but DON'T flush\n if (this.flushTimer !== null) {\n clearTimeout(this.flushTimer)\n this.flushTimer = null\n }\n // Discard remaining messages\n this.buffer = []\n }\n\n /**\n * Get statistics about buffer performance\n */\n getStats(): {\n totalMessages: number\n totalFlushes: number\n averageBatchSize: number\n currentBufferSize: number\n } {\n return {\n totalMessages: this.messageCount,\n totalFlushes: this.flushCount,\n averageBatchSize:\n this.flushCount > 0 ? this.messageCount / this.flushCount : 0,\n currentBufferSize: this.buffer.length,\n }\n }\n}\n"],
5
+ "mappings": "AA2CO,MAAM,mBAAmB;AAAA,EACtB,SAAoB,CAAC;AAAA,EACrB,aAAoC;AAAA,EAC3B;AAAA,EACA;AAAA,EACT,eAAe;AAAA,EACf,aAAa;AAAA,EAErB,YACE,eACA,UAAqC,CAAC,GACtC;AACA,SAAK,gBAAgB;AACrB,SAAK,UAAU;AAAA,MACb,eAAe,QAAQ,iBAAiB;AAAA,MACxC,cAAc,QAAQ,gBAAgB;AAAA,MACtC,OAAO,QAAQ,SAAS;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,SAAwB;AAC1B,SAAK,OAAO,KAAK,OAAO;AACxB,SAAK;AAEL,QAAI,KAAK,QAAQ,OAAO;AACtB,cAAQ;AAAA,QACN,+CAA+C,KAAK,OAAO,MAAM,IAAI,KAAK,QAAQ,YAAY;AAAA,MAChG;AAAA,IACF;AAGA,QAAI,KAAK,OAAO,UAAU,KAAK,QAAQ,cAAc;AACnD,UAAI,KAAK,QAAQ,OAAO;AACtB,gBAAQ,IAAI,2DAA2D;AAAA,MACzE;AACA,WAAK,MAAM;AACX;AAAA,IACF;AAGA,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAAsB;AAE5B,QAAI,KAAK,eAAe,MAAM;AAC5B,mBAAa,KAAK,UAAU;AAAA,IAC9B;AAGA,SAAK,aAAa,WAAW,MAAM;AACjC,WAAK,MAAM;AAAA,IACb,GAAG,KAAK,QAAQ,aAAa;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,QAAI,KAAK,OAAO,WAAW,GAAG;AAC5B;AAAA,IACF;AAEA,UAAM,kBAAkB,CAAC,GAAG,KAAK,MAAM;AACvC,SAAK,SAAS,CAAC;AACf,SAAK;AAEL,QAAI,KAAK,eAAe,MAAM;AAC5B,mBAAa,KAAK,UAAU;AAC5B,WAAK,aAAa;AAAA,IACpB;AAEA,QAAI,KAAK,QAAQ,OAAO;AACtB,cAAQ;AAAA,QACN,+BAA+B,KAAK,UAAU,KAAK,gBAAgB,MAAM;AAAA,MAC3E;AAAA,IACF;AAEA,SAAK,cAAc,eAAe;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,UAAgB;AAEd,QAAI,KAAK,eAAe,MAAM;AAC5B,mBAAa,KAAK,UAAU;AAC5B,WAAK,aAAa;AAAA,IACpB;AAEA,SAAK,SAAS,CAAC;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,WAKE;AACA,WAAO;AAAA,MACL,eAAe,KAAK;AAAA,MACpB,cAAc,KAAK;AAAA,MACnB,kBACE,KAAK,aAAa,IAAI,KAAK,eAAe,KAAK,aAAa;AAAA,MAC9D,mBAAmB,KAAK,OAAO;AAAA,IACjC;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -132,6 +132,11 @@ function detectShell() {
132
132
  ].join("\n");
133
133
  throw new Error(hint);
134
134
  }
135
+ const shellCrashListeners = /* @__PURE__ */ new Set();
136
+ function onShellCrash(callback) {
137
+ shellCrashListeners.add(callback);
138
+ return () => shellCrashListeners.delete(callback);
139
+ }
135
140
  class PersistentShell {
136
141
  commandQueue = [];
137
142
  isExecuting = false;
@@ -167,6 +172,13 @@ class PersistentShell {
167
172
  this.shell.on("exit", (code, signal) => {
168
173
  if (code) {
169
174
  logError(`Shell exited with code ${code} and signal ${signal}`);
175
+ for (const listener of shellCrashListeners) {
176
+ try {
177
+ listener(code, signal);
178
+ } catch (e) {
179
+ logError(`Shell crash listener error: ${e}`);
180
+ }
181
+ }
170
182
  }
171
183
  for (const file of [
172
184
  this.statusFile,
@@ -256,6 +268,143 @@ class PersistentShell {
256
268
  this.processQueue();
257
269
  });
258
270
  }
271
+ /**
272
+ * Execute a command with streaming output.
273
+ * Yields partial stdout/stderr as the command runs.
274
+ *
275
+ * @param command - The command to execute
276
+ * @param abortSignal - Optional signal to abort the command
277
+ * @param timeout - Optional timeout in milliseconds
278
+ * @param streamInterval - Interval in ms to check for new output (default: 50ms)
279
+ */
280
+ async *execStreaming(command, abortSignal, timeout, streamInterval = 50) {
281
+ while (this.isExecuting) {
282
+ await new Promise((resolve2) => setTimeout(resolve2, 10));
283
+ }
284
+ yield* this.execStreaming_(command, abortSignal, timeout, streamInterval);
285
+ }
286
+ async *execStreaming_(command, abortSignal, timeout, streamInterval = 50) {
287
+ const quotedCommand = quoteForBash(command);
288
+ try {
289
+ if (this.shellType === "wsl") {
290
+ execFileSync("wsl.exe", ["-e", "bash", "-n", "-c", command], {
291
+ stdio: "ignore",
292
+ timeout: 1e3
293
+ });
294
+ } else if (this.shellType === "msys") {
295
+ execFileSync(this.binShell, ["-n", "-c", command], {
296
+ stdio: "ignore",
297
+ timeout: 1e3
298
+ });
299
+ } else {
300
+ execFileSync(this.binShell, ["-n", "-c", command], {
301
+ stdio: "ignore",
302
+ timeout: 1e3
303
+ });
304
+ }
305
+ } catch (error) {
306
+ const execError = error;
307
+ const actualExitCode = execError?.status ?? execError?.code ?? 2;
308
+ const errorStr = execError?.stderr?.toString() || execError?.message || String(error || "");
309
+ yield {
310
+ type: "result",
311
+ stdout: "",
312
+ stderr: errorStr,
313
+ code: actualExitCode,
314
+ interrupted: false
315
+ };
316
+ return;
317
+ }
318
+ const commandTimeout = timeout || DEFAULT_TIMEOUT;
319
+ this.commandInterrupted = false;
320
+ this.isExecuting = true;
321
+ const killChildren = () => this.killChildren();
322
+ if (abortSignal) {
323
+ abortSignal.addEventListener("abort", killChildren);
324
+ }
325
+ try {
326
+ fs.writeFileSync(this.stdoutFile, "");
327
+ fs.writeFileSync(this.stderrFile, "");
328
+ fs.writeFileSync(this.statusFile, "");
329
+ const commandParts = [];
330
+ commandParts.push(
331
+ `eval ${quotedCommand} < /dev/null > ${quoteForBash(this.stdoutFileBashPath)} 2> ${quoteForBash(this.stderrFileBashPath)}`
332
+ );
333
+ commandParts.push(`EXEC_EXIT_CODE=$?`);
334
+ if (this.shellType === "msys") {
335
+ commandParts.push(`pwd -W > ${quoteForBash(this.cwdFileBashPath)}`);
336
+ } else {
337
+ commandParts.push(`pwd > ${quoteForBash(this.cwdFileBashPath)}`);
338
+ }
339
+ commandParts.push(
340
+ `echo $EXEC_EXIT_CODE > ${quoteForBash(this.statusFileBashPath)}`
341
+ );
342
+ this.sendToShell(commandParts.join("\n"));
343
+ const start = Date.now();
344
+ let lastStdout = "";
345
+ let lastStderr = "";
346
+ while (true) {
347
+ let statusFileSize = 0;
348
+ if (fs.existsSync(this.statusFile)) {
349
+ statusFileSize = fs.statSync(this.statusFile).size;
350
+ }
351
+ const isTimeout = Date.now() - start > commandTimeout;
352
+ const isComplete = statusFileSize > 0 || isTimeout || this.commandInterrupted;
353
+ let currentStdout = "";
354
+ let currentStderr = "";
355
+ if (fs.existsSync(this.stdoutFile)) {
356
+ try {
357
+ currentStdout = fs.readFileSync(this.stdoutFile, "utf8");
358
+ } catch {
359
+ }
360
+ }
361
+ if (fs.existsSync(this.stderrFile)) {
362
+ try {
363
+ currentStderr = fs.readFileSync(this.stderrFile, "utf8");
364
+ } catch {
365
+ }
366
+ }
367
+ const newStdout = currentStdout.slice(lastStdout.length);
368
+ const newStderr = currentStderr.slice(lastStderr.length);
369
+ if (newStdout || newStderr) {
370
+ yield {
371
+ type: "chunk",
372
+ stdout: newStdout,
373
+ stderr: newStderr
374
+ };
375
+ lastStdout = currentStdout;
376
+ lastStderr = currentStderr;
377
+ }
378
+ if (isComplete) {
379
+ if (isTimeout && !this.commandInterrupted) {
380
+ this.killChildren();
381
+ currentStderr += (currentStderr ? "\n" : "") + "Command execution timed out";
382
+ }
383
+ let code;
384
+ if (statusFileSize > 0) {
385
+ code = Number(fs.readFileSync(this.statusFile, "utf8"));
386
+ } else {
387
+ code = SIGTERM_CODE;
388
+ }
389
+ yield {
390
+ type: "result",
391
+ stdout: currentStdout,
392
+ stderr: currentStderr,
393
+ code,
394
+ interrupted: this.commandInterrupted
395
+ };
396
+ return;
397
+ }
398
+ await new Promise((resolve2) => setTimeout(resolve2, streamInterval));
399
+ }
400
+ } finally {
401
+ this.isExecuting = false;
402
+ if (abortSignal) {
403
+ abortSignal.removeEventListener("abort", killChildren);
404
+ }
405
+ this.processQueue();
406
+ }
407
+ }
259
408
  async exec_(command, timeout) {
260
409
  const quotedCommand = quoteForBash(command);
261
410
  try {
@@ -371,6 +520,7 @@ class PersistentShell {
371
520
  }
372
521
  }
373
522
  export {
374
- PersistentShell
523
+ PersistentShell,
524
+ onShellCrash
375
525
  };
376
526
  //# sourceMappingURL=PersistentShell.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/PersistentShell.ts"],
4
- "sourcesContent": ["import * as fs from 'fs'\nimport { homedir } from 'os'\nimport { existsSync } from 'fs'\nimport shellquote from 'shell-quote'\nimport { spawn, execSync, execFileSync, type ChildProcess } from 'child_process'\nimport { isAbsolute, resolve, join } from 'path'\nimport { logError } from './log'\nimport * as os from 'os'\nimport { PRODUCT_COMMAND } from '@constants/product'\n\ntype ExecResult = {\n stdout: string\n stderr: string\n code: number\n interrupted: boolean\n}\ntype QueuedCommand = {\n command: string\n abortSignal?: AbortSignal\n timeout?: number\n resolve: (result: ExecResult) => void\n reject: (error: Error) => void\n}\n\nconst TEMPFILE_PREFIX = os.tmpdir() + `/${PRODUCT_COMMAND}-`\nconst DEFAULT_TIMEOUT = 30 * 60 * 1000\nconst SIGTERM_CODE = 143 // Standard exit code for SIGTERM\nconst FILE_SUFFIXES = {\n STATUS: '-status',\n STDOUT: '-stdout',\n STDERR: '-stderr',\n CWD: '-cwd',\n}\nconst SHELL_CONFIGS: Record<string, string> = {\n '/bin/bash': '.bashrc',\n '/bin/zsh': '.zshrc',\n}\n\ntype DetectedShell = {\n bin: string\n args: string[]\n type: 'posix' | 'msys' | 'wsl'\n}\n\nfunction quoteForBash(str: string): string {\n return `'${str.replace(/'/g, \"'\\\\''\")}'`\n}\n\nfunction toBashPath(pathStr: string, type: 'posix' | 'msys' | 'wsl'): string {\n // Already POSIX absolute path\n if (pathStr.startsWith('/')) return pathStr\n if (type === 'posix') return pathStr\n\n // Normalize backslashes\n const normalized = pathStr.replace(/\\\\/g, '/').replace(/\\\\\\\\/g, '/')\n const driveMatch = /^[A-Za-z]:/.exec(normalized)\n if (driveMatch) {\n const drive = normalized[0].toLowerCase()\n const rest = normalized.slice(2)\n if (type === 'msys') {\n return `/` + drive + (rest.startsWith('/') ? rest : `/${rest}`)\n }\n // wsl\n return `/mnt/` + drive + (rest.startsWith('/') ? rest : `/${rest}`)\n }\n // Relative path: just convert slashes\n return normalized\n}\n\nfunction fileExists(p: string | undefined): p is string {\n return !!p && existsSync(p)\n}\n\n// Robust PATH splitter for Windows and POSIX\nfunction splitPathEntries(\n pathEnv: string,\n platform: NodeJS.Platform,\n): string[] {\n if (!pathEnv) return []\n\n // POSIX: ':' is the separator\n if (platform !== 'win32') {\n return pathEnv\n .split(':')\n .map(s => s.trim().replace(/^\"|\"$/g, ''))\n .filter(Boolean)\n }\n\n // Windows: primarily ';', but some environments may use ':'\n // We must not split drive letters like 'C:\\\\' or 'D:foo\\\\bar'\n const entries: string[] = []\n let current = ''\n const pushCurrent = () => {\n const cleaned = current.trim().replace(/^\"|\"$/g, '')\n if (cleaned) entries.push(cleaned)\n current = ''\n }\n\n for (let i = 0; i < pathEnv.length; i++) {\n const ch = pathEnv[i]\n\n if (ch === ';') {\n pushCurrent()\n continue\n }\n\n if (ch === ':') {\n const segmentLength = current.length\n const firstChar = current[0]\n const isDriveLetterPrefix =\n segmentLength === 1 && /[A-Za-z]/.test(firstChar || '')\n // Treat ':' as separator only if it's NOT the drive letter colon\n if (!isDriveLetterPrefix) {\n pushCurrent()\n continue\n }\n }\n\n current += ch\n }\n\n // Flush the final segment\n pushCurrent()\n\n return entries\n}\n\nfunction detectShell(): DetectedShell {\n const isWin = process.platform === 'win32'\n if (!isWin) {\n const bin = process.env.SHELL || '/bin/bash'\n return { bin, args: ['-l'], type: 'posix' }\n }\n\n // 1) Respect SHELL if it points to a bash.exe that exists\n if (\n process.env.SHELL &&\n /bash\\.exe$/i.test(process.env.SHELL) &&\n existsSync(process.env.SHELL)\n ) {\n return { bin: process.env.SHELL, args: [], type: 'msys' }\n }\n\n // 1.1) Explicit override (MINTO_BASH or KODE_BASH for backward compatibility)\n const customBash = process.env.MINTO_BASH ?? process.env.KODE_BASH\n if (customBash && existsSync(customBash)) {\n return { bin: customBash, args: [], type: 'msys' }\n }\n\n // 2) Common Git Bash/MSYS2 locations\n const programFiles = [\n process.env['ProgramFiles'],\n process.env['ProgramFiles(x86)'],\n process.env['ProgramW6432'],\n ].filter(Boolean) as string[]\n\n const localAppData = process.env['LocalAppData']\n\n const candidates: string[] = []\n for (const base of programFiles) {\n candidates.push(\n join(base, 'Git', 'bin', 'bash.exe'),\n join(base, 'Git', 'usr', 'bin', 'bash.exe'),\n )\n }\n if (localAppData) {\n candidates.push(\n join(localAppData, 'Programs', 'Git', 'bin', 'bash.exe'),\n join(localAppData, 'Programs', 'Git', 'usr', 'bin', 'bash.exe'),\n )\n }\n // MSYS2 default\n candidates.push('C:/msys64/usr/bin/bash.exe')\n\n for (const c of candidates) {\n if (existsSync(c)) {\n return { bin: c, args: [], type: 'msys' }\n }\n }\n\n // 2.1) Search in PATH for bash.exe\n const pathEnv = process.env.PATH || process.env.Path || process.env.path || ''\n const pathEntries = splitPathEntries(pathEnv, process.platform)\n for (const p of pathEntries) {\n const candidate = join(p, 'bash.exe')\n if (existsSync(candidate)) {\n return { bin: candidate, args: [], type: 'msys' }\n }\n }\n\n // 3) WSL\n try {\n // Quick probe to ensure WSL+bash exists\n execSync('wsl.exe -e bash -lc \"echo MINTO_OK\"', {\n stdio: 'ignore',\n timeout: 1500,\n })\n return { bin: 'wsl.exe', args: ['-e', 'bash', '-l'], type: 'wsl' }\n } catch {}\n\n // 4) Last resort: meaningful error\n const hint = [\n '\u65E0\u6CD5\u627E\u5230\u53EF\u7528\u7684 bash\u3002\u8BF7\u5B89\u88C5 Git for Windows \u6216\u542F\u7528 WSL\u3002',\n '\u63A8\u8350\u5B89\u88C5 Git: https://git-scm.com/download/win',\n '\u6216\u542F\u7528 WSL \u5E76\u5B89\u88C5 Ubuntu: https://learn.microsoft.com/windows/wsl/install',\n ].join('\\n')\n throw new Error(hint)\n}\n\nexport class PersistentShell {\n private commandQueue: QueuedCommand[] = []\n private isExecuting: boolean = false\n private shell: ChildProcess\n private isAlive: boolean = true\n private commandInterrupted: boolean = false\n private statusFile: string\n private stdoutFile: string\n private stderrFile: string\n private cwdFile: string\n private cwd: string\n private binShell: string\n private shellArgs: string[]\n private shellType: 'posix' | 'msys' | 'wsl'\n private statusFileBashPath: string\n private stdoutFileBashPath: string\n private stderrFileBashPath: string\n private cwdFileBashPath: string\n\n constructor(cwd: string) {\n const { bin, args, type } = detectShell()\n this.binShell = bin\n this.shellArgs = args\n this.shellType = type\n\n this.shell = spawn(this.binShell, this.shellArgs, {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd,\n env: {\n ...process.env,\n GIT_EDITOR: 'true',\n },\n })\n\n this.cwd = cwd\n\n this.shell.on('exit', (code, signal) => {\n if (code) {\n // TODO: It would be nice to alert the user that shell crashed\n logError(`Shell exited with code ${code} and signal ${signal}`)\n }\n for (const file of [\n this.statusFile,\n this.stdoutFile,\n this.stderrFile,\n this.cwdFile,\n ]) {\n if (fs.existsSync(file)) {\n fs.unlinkSync(file)\n }\n }\n this.isAlive = false\n })\n\n const id = Math.floor(Math.random() * 0x10000)\n .toString(16)\n .padStart(4, '0')\n\n this.statusFile = TEMPFILE_PREFIX + id + FILE_SUFFIXES.STATUS\n this.stdoutFile = TEMPFILE_PREFIX + id + FILE_SUFFIXES.STDOUT\n this.stderrFile = TEMPFILE_PREFIX + id + FILE_SUFFIXES.STDERR\n this.cwdFile = TEMPFILE_PREFIX + id + FILE_SUFFIXES.CWD\n for (const file of [this.statusFile, this.stdoutFile, this.stderrFile]) {\n fs.writeFileSync(file, '')\n }\n // Initialize CWD file with initial directory\n fs.writeFileSync(this.cwdFile, cwd)\n\n // Compute bash-visible paths for redirections\n this.statusFileBashPath = toBashPath(this.statusFile, this.shellType)\n this.stdoutFileBashPath = toBashPath(this.stdoutFile, this.shellType)\n this.stderrFileBashPath = toBashPath(this.stderrFile, this.shellType)\n this.cwdFileBashPath = toBashPath(this.cwdFile, this.shellType)\n\n // Source ~/.bashrc when available (avoid login shells on MSYS to prevent cwd resets)\n if (this.shellType === 'msys') {\n // Use non-login shell; explicitly source but keep working directory\n this.sendToShell('[ -f ~/.bashrc ] && source ~/.bashrc || true')\n // Ensure CWD file reflects current Windows path immediately on MSYS\n this.sendToShell(`pwd -W > ${quoteForBash(this.cwdFileBashPath)}`)\n } else {\n this.sendToShell('[ -f ~/.bashrc ] && source ~/.bashrc || true')\n }\n }\n\n private static instance: PersistentShell | null = null\n\n static restart() {\n if (PersistentShell.instance) {\n PersistentShell.instance.close()\n PersistentShell.instance = null\n }\n }\n\n static getInstance(): PersistentShell {\n if (!PersistentShell.instance || !PersistentShell.instance.isAlive) {\n PersistentShell.instance = new PersistentShell(process.cwd())\n }\n return PersistentShell.instance\n }\n\n killChildren() {\n const parentPid = this.shell.pid\n try {\n const childPids = execSync(`pgrep -P ${parentPid}`)\n .toString()\n .trim()\n .split('\\n')\n .filter(Boolean) // Filter out empty strings\n\n childPids.forEach(pid => {\n try {\n process.kill(Number(pid), 'SIGTERM')\n } catch (error) {\n logError(`Failed to kill process ${pid}: ${error}`)\n }\n })\n } catch {\n // pgrep returns non-zero when no processes are found - this is expected\n } finally {\n this.commandInterrupted = true\n }\n }\n\n private async processQueue() {\n /**\n * Processes commands from the queue one at a time.\n * Concurrency invariants:\n * - Only one instance runs at a time (controlled by isExecuting)\n * - Is the only caller of updateCwd() in the system\n * - Calls updateCwd() after each command completes\n * - Ensures commands execute serially via the queue\n * - Handles interruption via abortSignal by calling killChildren()\n * - Cleans up abortSignal listeners after command completion or interruption\n */\n if (this.isExecuting || this.commandQueue.length === 0) return\n\n this.isExecuting = true\n const { command, abortSignal, timeout, resolve, reject } =\n this.commandQueue.shift()!\n\n const killChildren = () => this.killChildren()\n if (abortSignal) {\n abortSignal.addEventListener('abort', killChildren)\n }\n\n try {\n const result = await this.exec_(command, timeout)\n\n // No need to update cwd - it's handled in exec_ via the CWD file\n\n resolve(result)\n } catch (error) {\n reject(error as Error)\n } finally {\n this.isExecuting = false\n if (abortSignal) {\n abortSignal.removeEventListener('abort', killChildren)\n }\n // Process next command in queue\n this.processQueue()\n }\n }\n\n async exec(\n command: string,\n abortSignal?: AbortSignal,\n timeout?: number,\n ): Promise<ExecResult> {\n return new Promise((resolve, reject) => {\n this.commandQueue.push({ command, abortSignal, timeout, resolve, reject })\n this.processQueue()\n })\n }\n\n private async exec_(command: string, timeout?: number): Promise<ExecResult> {\n /**\n * Direct command execution without going through the queue.\n * Concurrency invariants:\n * - Not safe for concurrent calls (uses shared files)\n * - Called only when queue is idle\n * - Relies on file-based IPC to handle shell interaction\n * - Does not modify the command queue state\n * - Tracks interruption state via commandInterrupted flag\n * - Resets interruption state at start of new command\n * - Reports interruption status in result object\n *\n * Exit Code & CWD Handling:\n * - Executes command and immediately captures its exit code into a shell variable\n * - Updates the CWD file with the working directory after capturing exit code\n * - Writes the preserved exit code to the status file as the final step\n * - This sequence eliminates race conditions between exit code capture and CWD updates\n * - The pwd() method reads the CWD file directly for current directory info\n */\n const quotedCommand = quoteForBash(command)\n\n // Check the syntax of the command\n try {\n if (this.shellType === 'wsl') {\n // On Windows WSL, avoid shell string quoting issues by using argv form\n execFileSync('wsl.exe', ['-e', 'bash', '-n', '-c', command], {\n stdio: 'ignore',\n timeout: 1000,\n })\n } else if (this.shellType === 'msys') {\n // On Windows Git Bash/MSYS, use execFileSync to bypass cmd.exe parsing\n execFileSync(this.binShell, ['-n', '-c', command], {\n stdio: 'ignore',\n timeout: 1000,\n })\n } else {\n // POSIX platforms: keep existing behavior\n execSync(`${this.binShell} -n -c ${quotedCommand}`, {\n stdio: 'ignore',\n timeout: 1000,\n })\n }\n } catch (error) {\n // If there's a syntax error, return an error with the actual exit code\n const execError = error as any\n const actualExitCode = execError?.status ?? execError?.code ?? 2 // Default to 2 (syntax error) if no code available\n const errorStr =\n execError?.stderr?.toString() ||\n execError?.message ||\n String(error || '')\n\n return Promise.resolve({\n stdout: '',\n stderr: errorStr,\n code: actualExitCode,\n interrupted: false,\n })\n }\n\n const commandTimeout = timeout || DEFAULT_TIMEOUT\n // Reset interrupted state for new command\n this.commandInterrupted = false\n return new Promise<ExecResult>(resolve => {\n // Truncate output files\n fs.writeFileSync(this.stdoutFile, '')\n fs.writeFileSync(this.stderrFile, '')\n fs.writeFileSync(this.statusFile, '')\n // Break up the command sequence for clarity using an array of commands\n const commandParts = []\n\n // 1. Execute the main command with redirections\n commandParts.push(\n `eval ${quotedCommand} < /dev/null > ${quoteForBash(this.stdoutFileBashPath)} 2> ${quoteForBash(this.stderrFileBashPath)}`,\n )\n\n // 2. Capture exit code immediately after command execution to avoid losing it\n commandParts.push(`EXEC_EXIT_CODE=$?`)\n\n // 3. Update CWD file (use Windows path on MSYS to keep Node path checks correct)\n if (this.shellType === 'msys') {\n commandParts.push(`pwd -W > ${quoteForBash(this.cwdFileBashPath)}`)\n } else {\n commandParts.push(`pwd > ${quoteForBash(this.cwdFileBashPath)}`)\n }\n\n // 4. Write the preserved exit code to status file to avoid race with pwd\n commandParts.push(\n `echo $EXEC_EXIT_CODE > ${quoteForBash(this.statusFileBashPath)}`,\n )\n\n // Send the combined commands as a single operation to maintain atomicity\n this.sendToShell(commandParts.join('\\n'))\n\n // Check for command completion or timeout\n const start = Date.now()\n const checkCompletion = setInterval(() => {\n try {\n let statusFileSize = 0\n if (fs.existsSync(this.statusFile)) {\n statusFileSize = fs.statSync(this.statusFile).size\n }\n\n if (\n statusFileSize > 0 ||\n Date.now() - start > commandTimeout ||\n this.commandInterrupted\n ) {\n clearInterval(checkCompletion)\n const stdout = fs.existsSync(this.stdoutFile)\n ? fs.readFileSync(this.stdoutFile, 'utf8')\n : ''\n let stderr = fs.existsSync(this.stderrFile)\n ? fs.readFileSync(this.stderrFile, 'utf8')\n : ''\n let code: number\n if (statusFileSize) {\n code = Number(fs.readFileSync(this.statusFile, 'utf8'))\n } else {\n // Timeout occurred - kill any running processes\n this.killChildren()\n code = SIGTERM_CODE\n stderr += (stderr ? '\\n' : '') + 'Command execution timed out'\n }\n resolve({\n stdout,\n stderr,\n code,\n interrupted: this.commandInterrupted,\n })\n }\n } catch {\n // Ignore file system errors during polling - they are expected\n // as we check for completion before files exist\n }\n }, 10) // increasing this will introduce latency\n })\n }\n\n private sendToShell(command: string) {\n try {\n this.shell!.stdin!.write(command + '\\n')\n } catch (error) {\n const errorString =\n error instanceof Error\n ? error.message\n : String(error || 'Unknown error')\n logError(`Error in sendToShell: ${errorString}`)\n\n throw error\n }\n }\n\n pwd(): string {\n try {\n const newCwd = fs.readFileSync(this.cwdFile, 'utf8').trim()\n if (newCwd) {\n this.cwd = newCwd\n }\n } catch (error) {\n logError(`Shell pwd error ${error}`)\n }\n // Always return the cached value\n return this.cwd\n }\n\n async setCwd(cwd: string) {\n const resolved = isAbsolute(cwd) ? cwd : resolve(process.cwd(), cwd)\n if (!existsSync(resolved)) {\n throw new Error(`Path \"${resolved}\" does not exist`)\n }\n const bashPath = toBashPath(resolved, this.shellType)\n await this.exec(`cd ${quoteForBash(bashPath)}`)\n }\n\n close(): void {\n this.shell!.stdin!.end()\n this.shell.kill()\n }\n}\n"],
5
- "mappings": "AAAA,YAAY,QAAQ;AAEpB,SAAS,kBAAkB;AAE3B,SAAS,OAAO,UAAU,oBAAuC;AACjE,SAAS,YAAY,SAAS,YAAY;AAC1C,SAAS,gBAAgB;AACzB,YAAY,QAAQ;AACpB,SAAS,uBAAuB;AAgBhC,MAAM,kBAAkB,GAAG,OAAO,IAAI,IAAI,eAAe;AACzD,MAAM,kBAAkB,KAAK,KAAK;AAClC,MAAM,eAAe;AACrB,MAAM,gBAAgB;AAAA,EACpB,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,KAAK;AACP;AACA,MAAM,gBAAwC;AAAA,EAC5C,aAAa;AAAA,EACb,YAAY;AACd;AAQA,SAAS,aAAa,KAAqB;AACzC,SAAO,IAAI,IAAI,QAAQ,MAAM,OAAO,CAAC;AACvC;AAEA,SAAS,WAAW,SAAiB,MAAwC;AAE3E,MAAI,QAAQ,WAAW,GAAG,EAAG,QAAO;AACpC,MAAI,SAAS,QAAS,QAAO;AAG7B,QAAM,aAAa,QAAQ,QAAQ,OAAO,GAAG,EAAE,QAAQ,SAAS,GAAG;AACnE,QAAM,aAAa,aAAa,KAAK,UAAU;AAC/C,MAAI,YAAY;AACd,UAAM,QAAQ,WAAW,CAAC,EAAE,YAAY;AACxC,UAAM,OAAO,WAAW,MAAM,CAAC;AAC/B,QAAI,SAAS,QAAQ;AACnB,aAAO,MAAM,SAAS,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AAAA,IAC9D;AAEA,WAAO,UAAU,SAAS,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AAAA,EAClE;AAEA,SAAO;AACT;AAEA,SAAS,WAAW,GAAoC;AACtD,SAAO,CAAC,CAAC,KAAK,WAAW,CAAC;AAC5B;AAGA,SAAS,iBACP,SACA,UACU;AACV,MAAI,CAAC,QAAS,QAAO,CAAC;AAGtB,MAAI,aAAa,SAAS;AACxB,WAAO,QACJ,MAAM,GAAG,EACT,IAAI,OAAK,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC,EACvC,OAAO,OAAO;AAAA,EACnB;AAIA,QAAM,UAAoB,CAAC;AAC3B,MAAI,UAAU;AACd,QAAM,cAAc,MAAM;AACxB,UAAM,UAAU,QAAQ,KAAK,EAAE,QAAQ,UAAU,EAAE;AACnD,QAAI,QAAS,SAAQ,KAAK,OAAO;AACjC,cAAU;AAAA,EACZ;AAEA,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,KAAK,QAAQ,CAAC;AAEpB,QAAI,OAAO,KAAK;AACd,kBAAY;AACZ;AAAA,IACF;AAEA,QAAI,OAAO,KAAK;AACd,YAAM,gBAAgB,QAAQ;AAC9B,YAAM,YAAY,QAAQ,CAAC;AAC3B,YAAM,sBACJ,kBAAkB,KAAK,WAAW,KAAK,aAAa,EAAE;AAExD,UAAI,CAAC,qBAAqB;AACxB,oBAAY;AACZ;AAAA,MACF;AAAA,IACF;AAEA,eAAW;AAAA,EACb;AAGA,cAAY;AAEZ,SAAO;AACT;AAEA,SAAS,cAA6B;AACpC,QAAM,QAAQ,QAAQ,aAAa;AACnC,MAAI,CAAC,OAAO;AACV,UAAM,MAAM,QAAQ,IAAI,SAAS;AACjC,WAAO,EAAE,KAAK,MAAM,CAAC,IAAI,GAAG,MAAM,QAAQ;AAAA,EAC5C;AAGA,MACE,QAAQ,IAAI,SACZ,cAAc,KAAK,QAAQ,IAAI,KAAK,KACpC,WAAW,QAAQ,IAAI,KAAK,GAC5B;AACA,WAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,OAAO;AAAA,EAC1D;AAGA,QAAM,aAAa,QAAQ,IAAI,cAAc,QAAQ,IAAI;AACzD,MAAI,cAAc,WAAW,UAAU,GAAG;AACxC,WAAO,EAAE,KAAK,YAAY,MAAM,CAAC,GAAG,MAAM,OAAO;AAAA,EACnD;AAGA,QAAM,eAAe;AAAA,IACnB,QAAQ,IAAI,cAAc;AAAA,IAC1B,QAAQ,IAAI,mBAAmB;AAAA,IAC/B,QAAQ,IAAI,cAAc;AAAA,EAC5B,EAAE,OAAO,OAAO;AAEhB,QAAM,eAAe,QAAQ,IAAI,cAAc;AAE/C,QAAM,aAAuB,CAAC;AAC9B,aAAW,QAAQ,cAAc;AAC/B,eAAW;AAAA,MACT,KAAK,MAAM,OAAO,OAAO,UAAU;AAAA,MACnC,KAAK,MAAM,OAAO,OAAO,OAAO,UAAU;AAAA,IAC5C;AAAA,EACF;AACA,MAAI,cAAc;AAChB,eAAW;AAAA,MACT,KAAK,cAAc,YAAY,OAAO,OAAO,UAAU;AAAA,MACvD,KAAK,cAAc,YAAY,OAAO,OAAO,OAAO,UAAU;AAAA,IAChE;AAAA,EACF;AAEA,aAAW,KAAK,4BAA4B;AAE5C,aAAW,KAAK,YAAY;AAC1B,QAAI,WAAW,CAAC,GAAG;AACjB,aAAO,EAAE,KAAK,GAAG,MAAM,CAAC,GAAG,MAAM,OAAO;AAAA,IAC1C;AAAA,EACF;AAGA,QAAM,UAAU,QAAQ,IAAI,QAAQ,QAAQ,IAAI,QAAQ,QAAQ,IAAI,QAAQ;AAC5E,QAAM,cAAc,iBAAiB,SAAS,QAAQ,QAAQ;AAC9D,aAAW,KAAK,aAAa;AAC3B,UAAM,YAAY,KAAK,GAAG,UAAU;AACpC,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO,EAAE,KAAK,WAAW,MAAM,CAAC,GAAG,MAAM,OAAO;AAAA,IAClD;AAAA,EACF;AAGA,MAAI;AAEF,aAAS,uCAAuC;AAAA,MAC9C,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AACD,WAAO,EAAE,KAAK,WAAW,MAAM,CAAC,MAAM,QAAQ,IAAI,GAAG,MAAM,MAAM;AAAA,EACnE,QAAQ;AAAA,EAAC;AAGT,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACX,QAAM,IAAI,MAAM,IAAI;AACtB;AAEO,MAAM,gBAAgB;AAAA,EACnB,eAAgC,CAAC;AAAA,EACjC,cAAuB;AAAA,EACvB;AAAA,EACA,UAAmB;AAAA,EACnB,qBAA8B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,KAAa;AACvB,UAAM,EAAE,KAAK,MAAM,KAAK,IAAI,YAAY;AACxC,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,YAAY;AAEjB,SAAK,QAAQ,MAAM,KAAK,UAAU,KAAK,WAAW;AAAA,MAChD,OAAO,CAAC,QAAQ,QAAQ,MAAM;AAAA,MAC9B;AAAA,MACA,KAAK;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,YAAY;AAAA,MACd;AAAA,IACF,CAAC;AAED,SAAK,MAAM;AAEX,SAAK,MAAM,GAAG,QAAQ,CAAC,MAAM,WAAW;AACtC,UAAI,MAAM;AAER,iBAAS,0BAA0B,IAAI,eAAe,MAAM,EAAE;AAAA,MAChE;AACA,iBAAW,QAAQ;AAAA,QACjB,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,MACP,GAAG;AACD,YAAI,GAAG,WAAW,IAAI,GAAG;AACvB,aAAG,WAAW,IAAI;AAAA,QACpB;AAAA,MACF;AACA,WAAK,UAAU;AAAA,IACjB,CAAC;AAED,UAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,KAAO,EAC1C,SAAS,EAAE,EACX,SAAS,GAAG,GAAG;AAElB,SAAK,aAAa,kBAAkB,KAAK,cAAc;AACvD,SAAK,aAAa,kBAAkB,KAAK,cAAc;AACvD,SAAK,aAAa,kBAAkB,KAAK,cAAc;AACvD,SAAK,UAAU,kBAAkB,KAAK,cAAc;AACpD,eAAW,QAAQ,CAAC,KAAK,YAAY,KAAK,YAAY,KAAK,UAAU,GAAG;AACtE,SAAG,cAAc,MAAM,EAAE;AAAA,IAC3B;AAEA,OAAG,cAAc,KAAK,SAAS,GAAG;AAGlC,SAAK,qBAAqB,WAAW,KAAK,YAAY,KAAK,SAAS;AACpE,SAAK,qBAAqB,WAAW,KAAK,YAAY,KAAK,SAAS;AACpE,SAAK,qBAAqB,WAAW,KAAK,YAAY,KAAK,SAAS;AACpE,SAAK,kBAAkB,WAAW,KAAK,SAAS,KAAK,SAAS;AAG9D,QAAI,KAAK,cAAc,QAAQ;AAE7B,WAAK,YAAY,8CAA8C;AAE/D,WAAK,YAAY,YAAY,aAAa,KAAK,eAAe,CAAC,EAAE;AAAA,IACnE,OAAO;AACL,WAAK,YAAY,8CAA8C;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,OAAe,WAAmC;AAAA,EAElD,OAAO,UAAU;AACf,QAAI,gBAAgB,UAAU;AAC5B,sBAAgB,SAAS,MAAM;AAC/B,sBAAgB,WAAW;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,OAAO,cAA+B;AACpC,QAAI,CAAC,gBAAgB,YAAY,CAAC,gBAAgB,SAAS,SAAS;AAClE,sBAAgB,WAAW,IAAI,gBAAgB,QAAQ,IAAI,CAAC;AAAA,IAC9D;AACA,WAAO,gBAAgB;AAAA,EACzB;AAAA,EAEA,eAAe;AACb,UAAM,YAAY,KAAK,MAAM;AAC7B,QAAI;AACF,YAAM,YAAY,SAAS,YAAY,SAAS,EAAE,EAC/C,SAAS,EACT,KAAK,EACL,MAAM,IAAI,EACV,OAAO,OAAO;AAEjB,gBAAU,QAAQ,SAAO;AACvB,YAAI;AACF,kBAAQ,KAAK,OAAO,GAAG,GAAG,SAAS;AAAA,QACrC,SAAS,OAAO;AACd,mBAAS,0BAA0B,GAAG,KAAK,KAAK,EAAE;AAAA,QACpD;AAAA,MACF,CAAC;AAAA,IACH,QAAQ;AAAA,IAER,UAAE;AACA,WAAK,qBAAqB;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,MAAc,eAAe;AAW3B,QAAI,KAAK,eAAe,KAAK,aAAa,WAAW,EAAG;AAExD,SAAK,cAAc;AACnB,UAAM,EAAE,SAAS,aAAa,SAAS,SAAAA,UAAS,OAAO,IACrD,KAAK,aAAa,MAAM;AAE1B,UAAM,eAAe,MAAM,KAAK,aAAa;AAC7C,QAAI,aAAa;AACf,kBAAY,iBAAiB,SAAS,YAAY;AAAA,IACpD;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,MAAM,SAAS,OAAO;AAIhD,MAAAA,SAAQ,MAAM;AAAA,IAChB,SAAS,OAAO;AACd,aAAO,KAAc;AAAA,IACvB,UAAE;AACA,WAAK,cAAc;AACnB,UAAI,aAAa;AACf,oBAAY,oBAAoB,SAAS,YAAY;AAAA,MACvD;AAEA,WAAK,aAAa;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,KACJ,SACA,aACA,SACqB;AACrB,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACtC,WAAK,aAAa,KAAK,EAAE,SAAS,aAAa,SAAS,SAAAA,UAAS,OAAO,CAAC;AACzE,WAAK,aAAa;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,MAAM,SAAiB,SAAuC;AAmB1E,UAAM,gBAAgB,aAAa,OAAO;AAG1C,QAAI;AACF,UAAI,KAAK,cAAc,OAAO;AAE5B,qBAAa,WAAW,CAAC,MAAM,QAAQ,MAAM,MAAM,OAAO,GAAG;AAAA,UAC3D,OAAO;AAAA,UACP,SAAS;AAAA,QACX,CAAC;AAAA,MACH,WAAW,KAAK,cAAc,QAAQ;AAEpC,qBAAa,KAAK,UAAU,CAAC,MAAM,MAAM,OAAO,GAAG;AAAA,UACjD,OAAO;AAAA,UACP,SAAS;AAAA,QACX,CAAC;AAAA,MACH,OAAO;AAEL,iBAAS,GAAG,KAAK,QAAQ,UAAU,aAAa,IAAI;AAAA,UAClD,OAAO;AAAA,UACP,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AAEd,YAAM,YAAY;AAClB,YAAM,iBAAiB,WAAW,UAAU,WAAW,QAAQ;AAC/D,YAAM,WACJ,WAAW,QAAQ,SAAS,KAC5B,WAAW,WACX,OAAO,SAAS,EAAE;AAEpB,aAAO,QAAQ,QAAQ;AAAA,QACrB,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAEA,UAAM,iBAAiB,WAAW;AAElC,SAAK,qBAAqB;AAC1B,WAAO,IAAI,QAAoB,CAAAA,aAAW;AAExC,SAAG,cAAc,KAAK,YAAY,EAAE;AACpC,SAAG,cAAc,KAAK,YAAY,EAAE;AACpC,SAAG,cAAc,KAAK,YAAY,EAAE;AAEpC,YAAM,eAAe,CAAC;AAGtB,mBAAa;AAAA,QACX,QAAQ,aAAa,kBAAkB,aAAa,KAAK,kBAAkB,CAAC,OAAO,aAAa,KAAK,kBAAkB,CAAC;AAAA,MAC1H;AAGA,mBAAa,KAAK,mBAAmB;AAGrC,UAAI,KAAK,cAAc,QAAQ;AAC7B,qBAAa,KAAK,YAAY,aAAa,KAAK,eAAe,CAAC,EAAE;AAAA,MACpE,OAAO;AACL,qBAAa,KAAK,SAAS,aAAa,KAAK,eAAe,CAAC,EAAE;AAAA,MACjE;AAGA,mBAAa;AAAA,QACX,0BAA0B,aAAa,KAAK,kBAAkB,CAAC;AAAA,MACjE;AAGA,WAAK,YAAY,aAAa,KAAK,IAAI,CAAC;AAGxC,YAAM,QAAQ,KAAK,IAAI;AACvB,YAAM,kBAAkB,YAAY,MAAM;AACxC,YAAI;AACF,cAAI,iBAAiB;AACrB,cAAI,GAAG,WAAW,KAAK,UAAU,GAAG;AAClC,6BAAiB,GAAG,SAAS,KAAK,UAAU,EAAE;AAAA,UAChD;AAEA,cACE,iBAAiB,KACjB,KAAK,IAAI,IAAI,QAAQ,kBACrB,KAAK,oBACL;AACA,0BAAc,eAAe;AAC7B,kBAAM,SAAS,GAAG,WAAW,KAAK,UAAU,IACxC,GAAG,aAAa,KAAK,YAAY,MAAM,IACvC;AACJ,gBAAI,SAAS,GAAG,WAAW,KAAK,UAAU,IACtC,GAAG,aAAa,KAAK,YAAY,MAAM,IACvC;AACJ,gBAAI;AACJ,gBAAI,gBAAgB;AAClB,qBAAO,OAAO,GAAG,aAAa,KAAK,YAAY,MAAM,CAAC;AAAA,YACxD,OAAO;AAEL,mBAAK,aAAa;AAClB,qBAAO;AACP,yBAAW,SAAS,OAAO,MAAM;AAAA,YACnC;AACA,YAAAA,SAAQ;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,aAAa,KAAK;AAAA,YACpB,CAAC;AAAA,UACH;AAAA,QACF,QAAQ;AAAA,QAGR;AAAA,MACF,GAAG,EAAE;AAAA,IACP,CAAC;AAAA,EACH;AAAA,EAEQ,YAAY,SAAiB;AACnC,QAAI;AACF,WAAK,MAAO,MAAO,MAAM,UAAU,IAAI;AAAA,IACzC,SAAS,OAAO;AACd,YAAM,cACJ,iBAAiB,QACb,MAAM,UACN,OAAO,SAAS,eAAe;AACrC,eAAS,yBAAyB,WAAW,EAAE;AAE/C,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc;AACZ,QAAI;AACF,YAAM,SAAS,GAAG,aAAa,KAAK,SAAS,MAAM,EAAE,KAAK;AAC1D,UAAI,QAAQ;AACV,aAAK,MAAM;AAAA,MACb;AAAA,IACF,SAAS,OAAO;AACd,eAAS,mBAAmB,KAAK,EAAE;AAAA,IACrC;AAEA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,OAAO,KAAa;AACxB,UAAM,WAAW,WAAW,GAAG,IAAI,MAAM,QAAQ,QAAQ,IAAI,GAAG,GAAG;AACnE,QAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,YAAM,IAAI,MAAM,SAAS,QAAQ,kBAAkB;AAAA,IACrD;AACA,UAAM,WAAW,WAAW,UAAU,KAAK,SAAS;AACpD,UAAM,KAAK,KAAK,MAAM,aAAa,QAAQ,CAAC,EAAE;AAAA,EAChD;AAAA,EAEA,QAAc;AACZ,SAAK,MAAO,MAAO,IAAI;AACvB,SAAK,MAAM,KAAK;AAAA,EAClB;AACF;",
4
+ "sourcesContent": ["import * as fs from 'fs'\nimport { homedir } from 'os'\nimport { existsSync } from 'fs'\nimport shellquote from 'shell-quote'\nimport { spawn, execSync, execFileSync, type ChildProcess } from 'child_process'\nimport { isAbsolute, resolve, join } from 'path'\nimport { logError } from './log'\nimport * as os from 'os'\nimport { PRODUCT_COMMAND } from '@constants/product'\n\ntype ExecResult = {\n stdout: string\n stderr: string\n code: number\n interrupted: boolean\n}\n\n/**\n * Streaming output chunk from execStreaming\n */\nexport type StreamingOutput = {\n type: 'chunk'\n stdout: string\n stderr: string\n}\n\n/**\n * Final result from execStreaming\n */\nexport type StreamingResult = {\n type: 'result'\n stdout: string\n stderr: string\n code: number\n interrupted: boolean\n}\n\n/**\n * Union type for streaming generator yields\n */\nexport type StreamingYield = StreamingOutput | StreamingResult\ntype QueuedCommand = {\n command: string\n abortSignal?: AbortSignal\n timeout?: number\n resolve: (result: ExecResult) => void\n reject: (error: Error) => void\n}\n\nconst TEMPFILE_PREFIX = os.tmpdir() + `/${PRODUCT_COMMAND}-`\nconst DEFAULT_TIMEOUT = 30 * 60 * 1000\nconst SIGTERM_CODE = 143 // Standard exit code for SIGTERM\nconst FILE_SUFFIXES = {\n STATUS: '-status',\n STDOUT: '-stdout',\n STDERR: '-stderr',\n CWD: '-cwd',\n}\nconst SHELL_CONFIGS: Record<string, string> = {\n '/bin/bash': '.bashrc',\n '/bin/zsh': '.zshrc',\n}\n\ntype DetectedShell = {\n bin: string\n args: string[]\n type: 'posix' | 'msys' | 'wsl'\n}\n\nfunction quoteForBash(str: string): string {\n return `'${str.replace(/'/g, \"'\\\\''\")}'`\n}\n\nfunction toBashPath(pathStr: string, type: 'posix' | 'msys' | 'wsl'): string {\n // Already POSIX absolute path\n if (pathStr.startsWith('/')) return pathStr\n if (type === 'posix') return pathStr\n\n // Normalize backslashes\n const normalized = pathStr.replace(/\\\\/g, '/').replace(/\\\\\\\\/g, '/')\n const driveMatch = /^[A-Za-z]:/.exec(normalized)\n if (driveMatch) {\n const drive = normalized[0].toLowerCase()\n const rest = normalized.slice(2)\n if (type === 'msys') {\n return `/` + drive + (rest.startsWith('/') ? rest : `/${rest}`)\n }\n // wsl\n return `/mnt/` + drive + (rest.startsWith('/') ? rest : `/${rest}`)\n }\n // Relative path: just convert slashes\n return normalized\n}\n\nfunction fileExists(p: string | undefined): p is string {\n return !!p && existsSync(p)\n}\n\n// Robust PATH splitter for Windows and POSIX\nfunction splitPathEntries(\n pathEnv: string,\n platform: NodeJS.Platform,\n): string[] {\n if (!pathEnv) return []\n\n // POSIX: ':' is the separator\n if (platform !== 'win32') {\n return pathEnv\n .split(':')\n .map(s => s.trim().replace(/^\"|\"$/g, ''))\n .filter(Boolean)\n }\n\n // Windows: primarily ';', but some environments may use ':'\n // We must not split drive letters like 'C:\\\\' or 'D:foo\\\\bar'\n const entries: string[] = []\n let current = ''\n const pushCurrent = () => {\n const cleaned = current.trim().replace(/^\"|\"$/g, '')\n if (cleaned) entries.push(cleaned)\n current = ''\n }\n\n for (let i = 0; i < pathEnv.length; i++) {\n const ch = pathEnv[i]\n\n if (ch === ';') {\n pushCurrent()\n continue\n }\n\n if (ch === ':') {\n const segmentLength = current.length\n const firstChar = current[0]\n const isDriveLetterPrefix =\n segmentLength === 1 && /[A-Za-z]/.test(firstChar || '')\n // Treat ':' as separator only if it's NOT the drive letter colon\n if (!isDriveLetterPrefix) {\n pushCurrent()\n continue\n }\n }\n\n current += ch\n }\n\n // Flush the final segment\n pushCurrent()\n\n return entries\n}\n\nfunction detectShell(): DetectedShell {\n const isWin = process.platform === 'win32'\n if (!isWin) {\n const bin = process.env.SHELL || '/bin/bash'\n return { bin, args: ['-l'], type: 'posix' }\n }\n\n // 1) Respect SHELL if it points to a bash.exe that exists\n if (\n process.env.SHELL &&\n /bash\\.exe$/i.test(process.env.SHELL) &&\n existsSync(process.env.SHELL)\n ) {\n return { bin: process.env.SHELL, args: [], type: 'msys' }\n }\n\n // 1.1) Explicit override (MINTO_BASH or KODE_BASH for backward compatibility)\n const customBash = process.env.MINTO_BASH ?? process.env.KODE_BASH\n if (customBash && existsSync(customBash)) {\n return { bin: customBash, args: [], type: 'msys' }\n }\n\n // 2) Common Git Bash/MSYS2 locations\n const programFiles = [\n process.env['ProgramFiles'],\n process.env['ProgramFiles(x86)'],\n process.env['ProgramW6432'],\n ].filter(Boolean) as string[]\n\n const localAppData = process.env['LocalAppData']\n\n const candidates: string[] = []\n for (const base of programFiles) {\n candidates.push(\n join(base, 'Git', 'bin', 'bash.exe'),\n join(base, 'Git', 'usr', 'bin', 'bash.exe'),\n )\n }\n if (localAppData) {\n candidates.push(\n join(localAppData, 'Programs', 'Git', 'bin', 'bash.exe'),\n join(localAppData, 'Programs', 'Git', 'usr', 'bin', 'bash.exe'),\n )\n }\n // MSYS2 default\n candidates.push('C:/msys64/usr/bin/bash.exe')\n\n for (const c of candidates) {\n if (existsSync(c)) {\n return { bin: c, args: [], type: 'msys' }\n }\n }\n\n // 2.1) Search in PATH for bash.exe\n const pathEnv = process.env.PATH || process.env.Path || process.env.path || ''\n const pathEntries = splitPathEntries(pathEnv, process.platform)\n for (const p of pathEntries) {\n const candidate = join(p, 'bash.exe')\n if (existsSync(candidate)) {\n return { bin: candidate, args: [], type: 'msys' }\n }\n }\n\n // 3) WSL\n try {\n // Quick probe to ensure WSL+bash exists\n execSync('wsl.exe -e bash -lc \"echo MINTO_OK\"', {\n stdio: 'ignore',\n timeout: 1500,\n })\n return { bin: 'wsl.exe', args: ['-e', 'bash', '-l'], type: 'wsl' }\n } catch {}\n\n // 4) Last resort: meaningful error\n const hint = [\n '\u65E0\u6CD5\u627E\u5230\u53EF\u7528\u7684 bash\u3002\u8BF7\u5B89\u88C5 Git for Windows \u6216\u542F\u7528 WSL\u3002',\n '\u63A8\u8350\u5B89\u88C5 Git: https://git-scm.com/download/win',\n '\u6216\u542F\u7528 WSL \u5E76\u5B89\u88C5 Ubuntu: https://learn.microsoft.com/windows/wsl/install',\n ].join('\\n')\n throw new Error(hint)\n}\n\n// Shell crash callback type\nexport type ShellCrashCallback = (\n code: number | null,\n signal: NodeJS.Signals | null,\n) => void\n\n// Global shell crash listeners\nconst shellCrashListeners: Set<ShellCrashCallback> = new Set()\n\n/**\n * Register a callback to be notified when the persistent shell crashes\n */\nexport function onShellCrash(callback: ShellCrashCallback): () => void {\n shellCrashListeners.add(callback)\n return () => shellCrashListeners.delete(callback)\n}\n\nexport class PersistentShell {\n private commandQueue: QueuedCommand[] = []\n private isExecuting: boolean = false\n private shell: ChildProcess\n private isAlive: boolean = true\n private commandInterrupted: boolean = false\n private statusFile: string\n private stdoutFile: string\n private stderrFile: string\n private cwdFile: string\n private cwd: string\n private binShell: string\n private shellArgs: string[]\n private shellType: 'posix' | 'msys' | 'wsl'\n private statusFileBashPath: string\n private stdoutFileBashPath: string\n private stderrFileBashPath: string\n private cwdFileBashPath: string\n\n constructor(cwd: string) {\n const { bin, args, type } = detectShell()\n this.binShell = bin\n this.shellArgs = args\n this.shellType = type\n\n this.shell = spawn(this.binShell, this.shellArgs, {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd,\n env: {\n ...process.env,\n GIT_EDITOR: 'true',\n },\n })\n\n this.cwd = cwd\n\n this.shell.on('exit', (code, signal) => {\n if (code) {\n logError(`Shell exited with code ${code} and signal ${signal}`)\n // Notify all registered listeners about shell crash\n for (const listener of shellCrashListeners) {\n try {\n listener(code, signal)\n } catch (e) {\n // Don't let listener errors propagate\n logError(`Shell crash listener error: ${e}`)\n }\n }\n }\n for (const file of [\n this.statusFile,\n this.stdoutFile,\n this.stderrFile,\n this.cwdFile,\n ]) {\n if (fs.existsSync(file)) {\n fs.unlinkSync(file)\n }\n }\n this.isAlive = false\n })\n\n const id = Math.floor(Math.random() * 0x10000)\n .toString(16)\n .padStart(4, '0')\n\n this.statusFile = TEMPFILE_PREFIX + id + FILE_SUFFIXES.STATUS\n this.stdoutFile = TEMPFILE_PREFIX + id + FILE_SUFFIXES.STDOUT\n this.stderrFile = TEMPFILE_PREFIX + id + FILE_SUFFIXES.STDERR\n this.cwdFile = TEMPFILE_PREFIX + id + FILE_SUFFIXES.CWD\n for (const file of [this.statusFile, this.stdoutFile, this.stderrFile]) {\n fs.writeFileSync(file, '')\n }\n // Initialize CWD file with initial directory\n fs.writeFileSync(this.cwdFile, cwd)\n\n // Compute bash-visible paths for redirections\n this.statusFileBashPath = toBashPath(this.statusFile, this.shellType)\n this.stdoutFileBashPath = toBashPath(this.stdoutFile, this.shellType)\n this.stderrFileBashPath = toBashPath(this.stderrFile, this.shellType)\n this.cwdFileBashPath = toBashPath(this.cwdFile, this.shellType)\n\n // Source ~/.bashrc when available (avoid login shells on MSYS to prevent cwd resets)\n if (this.shellType === 'msys') {\n // Use non-login shell; explicitly source but keep working directory\n this.sendToShell('[ -f ~/.bashrc ] && source ~/.bashrc || true')\n // Ensure CWD file reflects current Windows path immediately on MSYS\n this.sendToShell(`pwd -W > ${quoteForBash(this.cwdFileBashPath)}`)\n } else {\n this.sendToShell('[ -f ~/.bashrc ] && source ~/.bashrc || true')\n }\n }\n\n private static instance: PersistentShell | null = null\n\n static restart() {\n if (PersistentShell.instance) {\n PersistentShell.instance.close()\n PersistentShell.instance = null\n }\n }\n\n static getInstance(): PersistentShell {\n if (!PersistentShell.instance || !PersistentShell.instance.isAlive) {\n PersistentShell.instance = new PersistentShell(process.cwd())\n }\n return PersistentShell.instance\n }\n\n killChildren() {\n const parentPid = this.shell.pid\n try {\n const childPids = execSync(`pgrep -P ${parentPid}`)\n .toString()\n .trim()\n .split('\\n')\n .filter(Boolean) // Filter out empty strings\n\n childPids.forEach(pid => {\n try {\n process.kill(Number(pid), 'SIGTERM')\n } catch (error) {\n logError(`Failed to kill process ${pid}: ${error}`)\n }\n })\n } catch {\n // pgrep returns non-zero when no processes are found - this is expected\n } finally {\n this.commandInterrupted = true\n }\n }\n\n private async processQueue() {\n /**\n * Processes commands from the queue one at a time.\n * Concurrency invariants:\n * - Only one instance runs at a time (controlled by isExecuting)\n * - Is the only caller of updateCwd() in the system\n * - Calls updateCwd() after each command completes\n * - Ensures commands execute serially via the queue\n * - Handles interruption via abortSignal by calling killChildren()\n * - Cleans up abortSignal listeners after command completion or interruption\n */\n if (this.isExecuting || this.commandQueue.length === 0) return\n\n this.isExecuting = true\n const { command, abortSignal, timeout, resolve, reject } =\n this.commandQueue.shift()!\n\n const killChildren = () => this.killChildren()\n if (abortSignal) {\n abortSignal.addEventListener('abort', killChildren)\n }\n\n try {\n const result = await this.exec_(command, timeout)\n\n // No need to update cwd - it's handled in exec_ via the CWD file\n\n resolve(result)\n } catch (error) {\n reject(error as Error)\n } finally {\n this.isExecuting = false\n if (abortSignal) {\n abortSignal.removeEventListener('abort', killChildren)\n }\n // Process next command in queue\n this.processQueue()\n }\n }\n\n async exec(\n command: string,\n abortSignal?: AbortSignal,\n timeout?: number,\n ): Promise<ExecResult> {\n return new Promise((resolve, reject) => {\n this.commandQueue.push({ command, abortSignal, timeout, resolve, reject })\n this.processQueue()\n })\n }\n\n /**\n * Execute a command with streaming output.\n * Yields partial stdout/stderr as the command runs.\n *\n * @param command - The command to execute\n * @param abortSignal - Optional signal to abort the command\n * @param timeout - Optional timeout in milliseconds\n * @param streamInterval - Interval in ms to check for new output (default: 50ms)\n */\n async *execStreaming(\n command: string,\n abortSignal?: AbortSignal,\n timeout?: number,\n streamInterval: number = 50,\n ): AsyncGenerator<StreamingYield, void, unknown> {\n // Wait for any previous command to finish first (queue ensures serial execution)\n while (this.isExecuting) {\n await new Promise(resolve => setTimeout(resolve, 10))\n }\n\n // Now execute with streaming\n yield* this.execStreaming_(command, abortSignal, timeout, streamInterval)\n }\n\n private async *execStreaming_(\n command: string,\n abortSignal?: AbortSignal,\n timeout?: number,\n streamInterval: number = 50,\n ): AsyncGenerator<StreamingYield, void, unknown> {\n const quotedCommand = quoteForBash(command)\n\n // Check syntax first (using existing pattern from exec_)\n try {\n if (this.shellType === 'wsl') {\n execFileSync('wsl.exe', ['-e', 'bash', '-n', '-c', command], {\n stdio: 'ignore',\n timeout: 1000,\n })\n } else if (this.shellType === 'msys') {\n execFileSync(this.binShell, ['-n', '-c', command], {\n stdio: 'ignore',\n timeout: 1000,\n })\n } else {\n // POSIX: use execFileSync for safety\n execFileSync(this.binShell, ['-n', '-c', command], {\n stdio: 'ignore',\n timeout: 1000,\n })\n }\n } catch (error) {\n const execError = error as any\n const actualExitCode = execError?.status ?? execError?.code ?? 2\n const errorStr =\n execError?.stderr?.toString() ||\n execError?.message ||\n String(error || '')\n\n yield {\n type: 'result',\n stdout: '',\n stderr: errorStr,\n code: actualExitCode,\n interrupted: false,\n }\n return\n }\n\n const commandTimeout = timeout || DEFAULT_TIMEOUT\n this.commandInterrupted = false\n this.isExecuting = true\n\n const killChildren = () => this.killChildren()\n if (abortSignal) {\n abortSignal.addEventListener('abort', killChildren)\n }\n\n try {\n // Truncate output files\n fs.writeFileSync(this.stdoutFile, '')\n fs.writeFileSync(this.stderrFile, '')\n fs.writeFileSync(this.statusFile, '')\n\n // Build command sequence\n const commandParts = []\n commandParts.push(\n `eval ${quotedCommand} < /dev/null > ${quoteForBash(this.stdoutFileBashPath)} 2> ${quoteForBash(this.stderrFileBashPath)}`,\n )\n commandParts.push(`EXEC_EXIT_CODE=$?`)\n if (this.shellType === 'msys') {\n commandParts.push(`pwd -W > ${quoteForBash(this.cwdFileBashPath)}`)\n } else {\n commandParts.push(`pwd > ${quoteForBash(this.cwdFileBashPath)}`)\n }\n commandParts.push(\n `echo $EXEC_EXIT_CODE > ${quoteForBash(this.statusFileBashPath)}`,\n )\n\n this.sendToShell(commandParts.join('\\n'))\n\n // Stream output while command runs\n const start = Date.now()\n let lastStdout = ''\n let lastStderr = ''\n\n while (true) {\n // Check for completion\n let statusFileSize = 0\n if (fs.existsSync(this.statusFile)) {\n statusFileSize = fs.statSync(this.statusFile).size\n }\n\n const isTimeout = Date.now() - start > commandTimeout\n const isComplete =\n statusFileSize > 0 || isTimeout || this.commandInterrupted\n\n // Read current output\n let currentStdout = ''\n let currentStderr = ''\n\n if (fs.existsSync(this.stdoutFile)) {\n try {\n currentStdout = fs.readFileSync(this.stdoutFile, 'utf8')\n } catch {\n // File might be being written to\n }\n }\n\n if (fs.existsSync(this.stderrFile)) {\n try {\n currentStderr = fs.readFileSync(this.stderrFile, 'utf8')\n } catch {\n // File might be being written to\n }\n }\n\n // Yield new content if there's any\n const newStdout = currentStdout.slice(lastStdout.length)\n const newStderr = currentStderr.slice(lastStderr.length)\n\n if (newStdout || newStderr) {\n yield {\n type: 'chunk',\n stdout: newStdout,\n stderr: newStderr,\n }\n lastStdout = currentStdout\n lastStderr = currentStderr\n }\n\n if (isComplete) {\n // Handle timeout\n if (isTimeout && !this.commandInterrupted) {\n this.killChildren()\n currentStderr +=\n (currentStderr ? '\\n' : '') + 'Command execution timed out'\n }\n\n // Get final exit code\n let code: number\n if (statusFileSize > 0) {\n code = Number(fs.readFileSync(this.statusFile, 'utf8'))\n } else {\n code = SIGTERM_CODE\n }\n\n yield {\n type: 'result',\n stdout: currentStdout,\n stderr: currentStderr,\n code,\n interrupted: this.commandInterrupted,\n }\n return\n }\n\n // Wait before next check\n await new Promise(resolve => setTimeout(resolve, streamInterval))\n }\n } finally {\n this.isExecuting = false\n if (abortSignal) {\n abortSignal.removeEventListener('abort', killChildren)\n }\n // Process next command in queue\n this.processQueue()\n }\n }\n\n private async exec_(command: string, timeout?: number): Promise<ExecResult> {\n /**\n * Direct command execution without going through the queue.\n * Concurrency invariants:\n * - Not safe for concurrent calls (uses shared files)\n * - Called only when queue is idle\n * - Relies on file-based IPC to handle shell interaction\n * - Does not modify the command queue state\n * - Tracks interruption state via commandInterrupted flag\n * - Resets interruption state at start of new command\n * - Reports interruption status in result object\n *\n * Exit Code & CWD Handling:\n * - Executes command and immediately captures its exit code into a shell variable\n * - Updates the CWD file with the working directory after capturing exit code\n * - Writes the preserved exit code to the status file as the final step\n * - This sequence eliminates race conditions between exit code capture and CWD updates\n * - The pwd() method reads the CWD file directly for current directory info\n */\n const quotedCommand = quoteForBash(command)\n\n // Check the syntax of the command\n try {\n if (this.shellType === 'wsl') {\n // On Windows WSL, avoid shell string quoting issues by using argv form\n execFileSync('wsl.exe', ['-e', 'bash', '-n', '-c', command], {\n stdio: 'ignore',\n timeout: 1000,\n })\n } else if (this.shellType === 'msys') {\n // On Windows Git Bash/MSYS, use execFileSync to bypass cmd.exe parsing\n execFileSync(this.binShell, ['-n', '-c', command], {\n stdio: 'ignore',\n timeout: 1000,\n })\n } else {\n // POSIX platforms: keep existing behavior\n execSync(`${this.binShell} -n -c ${quotedCommand}`, {\n stdio: 'ignore',\n timeout: 1000,\n })\n }\n } catch (error) {\n // If there's a syntax error, return an error with the actual exit code\n const execError = error as any\n const actualExitCode = execError?.status ?? execError?.code ?? 2 // Default to 2 (syntax error) if no code available\n const errorStr =\n execError?.stderr?.toString() ||\n execError?.message ||\n String(error || '')\n\n return Promise.resolve({\n stdout: '',\n stderr: errorStr,\n code: actualExitCode,\n interrupted: false,\n })\n }\n\n const commandTimeout = timeout || DEFAULT_TIMEOUT\n // Reset interrupted state for new command\n this.commandInterrupted = false\n return new Promise<ExecResult>(resolve => {\n // Truncate output files\n fs.writeFileSync(this.stdoutFile, '')\n fs.writeFileSync(this.stderrFile, '')\n fs.writeFileSync(this.statusFile, '')\n // Break up the command sequence for clarity using an array of commands\n const commandParts = []\n\n // 1. Execute the main command with redirections\n commandParts.push(\n `eval ${quotedCommand} < /dev/null > ${quoteForBash(this.stdoutFileBashPath)} 2> ${quoteForBash(this.stderrFileBashPath)}`,\n )\n\n // 2. Capture exit code immediately after command execution to avoid losing it\n commandParts.push(`EXEC_EXIT_CODE=$?`)\n\n // 3. Update CWD file (use Windows path on MSYS to keep Node path checks correct)\n if (this.shellType === 'msys') {\n commandParts.push(`pwd -W > ${quoteForBash(this.cwdFileBashPath)}`)\n } else {\n commandParts.push(`pwd > ${quoteForBash(this.cwdFileBashPath)}`)\n }\n\n // 4. Write the preserved exit code to status file to avoid race with pwd\n commandParts.push(\n `echo $EXEC_EXIT_CODE > ${quoteForBash(this.statusFileBashPath)}`,\n )\n\n // Send the combined commands as a single operation to maintain atomicity\n this.sendToShell(commandParts.join('\\n'))\n\n // Check for command completion or timeout\n const start = Date.now()\n const checkCompletion = setInterval(() => {\n try {\n let statusFileSize = 0\n if (fs.existsSync(this.statusFile)) {\n statusFileSize = fs.statSync(this.statusFile).size\n }\n\n if (\n statusFileSize > 0 ||\n Date.now() - start > commandTimeout ||\n this.commandInterrupted\n ) {\n clearInterval(checkCompletion)\n const stdout = fs.existsSync(this.stdoutFile)\n ? fs.readFileSync(this.stdoutFile, 'utf8')\n : ''\n let stderr = fs.existsSync(this.stderrFile)\n ? fs.readFileSync(this.stderrFile, 'utf8')\n : ''\n let code: number\n if (statusFileSize) {\n code = Number(fs.readFileSync(this.statusFile, 'utf8'))\n } else {\n // Timeout occurred - kill any running processes\n this.killChildren()\n code = SIGTERM_CODE\n stderr += (stderr ? '\\n' : '') + 'Command execution timed out'\n }\n resolve({\n stdout,\n stderr,\n code,\n interrupted: this.commandInterrupted,\n })\n }\n } catch {\n // Ignore file system errors during polling - they are expected\n // as we check for completion before files exist\n }\n }, 10) // increasing this will introduce latency\n })\n }\n\n private sendToShell(command: string) {\n try {\n this.shell!.stdin!.write(command + '\\n')\n } catch (error) {\n const errorString =\n error instanceof Error\n ? error.message\n : String(error || 'Unknown error')\n logError(`Error in sendToShell: ${errorString}`)\n\n throw error\n }\n }\n\n pwd(): string {\n try {\n const newCwd = fs.readFileSync(this.cwdFile, 'utf8').trim()\n if (newCwd) {\n this.cwd = newCwd\n }\n } catch (error) {\n logError(`Shell pwd error ${error}`)\n }\n // Always return the cached value\n return this.cwd\n }\n\n async setCwd(cwd: string) {\n const resolved = isAbsolute(cwd) ? cwd : resolve(process.cwd(), cwd)\n if (!existsSync(resolved)) {\n throw new Error(`Path \"${resolved}\" does not exist`)\n }\n const bashPath = toBashPath(resolved, this.shellType)\n await this.exec(`cd ${quoteForBash(bashPath)}`)\n }\n\n close(): void {\n this.shell!.stdin!.end()\n this.shell.kill()\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["resolve"]
7
7
  }
@@ -143,21 +143,11 @@ async function loadPluginAgents() {
143
143
  }
144
144
  async function loadAllAgents() {
145
145
  try {
146
- const userClaudeDir = join(homedir(), ".claude", "agents");
147
146
  const userMintoDir = join(homedir(), ".minto", "agents");
148
- const projectClaudeDir = join(getCwd(), ".claude", "agents");
149
147
  const projectMintoDir = join(getCwd(), ".minto", "agents");
150
- const [
151
- pluginAgents,
152
- userClaudeAgents,
153
- userMintoAgents,
154
- projectClaudeAgents,
155
- projectMintoAgents
156
- ] = await Promise.all([
148
+ const [pluginAgents, userMintoAgents, projectMintoAgents] = await Promise.all([
157
149
  loadPluginAgents(),
158
- scanAgentDirectory(userClaudeDir, "user"),
159
150
  scanAgentDirectory(userMintoDir, "user"),
160
- scanAgentDirectory(projectClaudeDir, "project"),
161
151
  scanAgentDirectory(projectMintoDir, "project")
162
152
  ]);
163
153
  const builtinAgents = [BUILTIN_GENERAL_PURPOSE];
@@ -168,15 +158,9 @@ async function loadAllAgents() {
168
158
  for (const agent of pluginAgents) {
169
159
  agentMap.set(agent.agentType, agent);
170
160
  }
171
- for (const agent of userClaudeAgents) {
172
- agentMap.set(agent.agentType, agent);
173
- }
174
161
  for (const agent of userMintoAgents) {
175
162
  agentMap.set(agent.agentType, agent);
176
163
  }
177
- for (const agent of projectClaudeAgents) {
178
- agentMap.set(agent.agentType, agent);
179
- }
180
164
  for (const agent of projectMintoAgents) {
181
165
  agentMap.set(agent.agentType, agent);
182
166
  }
@@ -184,9 +168,7 @@ async function loadAllAgents() {
184
168
  const allAgents = [
185
169
  ...builtinAgents,
186
170
  ...pluginAgents,
187
- ...userClaudeAgents,
188
171
  ...userMintoAgents,
189
- ...projectClaudeAgents,
190
172
  ...projectMintoAgents
191
173
  ];
192
174
  return { activeAgents, allAgents };
@@ -225,9 +207,7 @@ const getAvailableAgentTypes = memoize(async () => {
225
207
  let watchers = [];
226
208
  async function startAgentWatcher(onChange) {
227
209
  await stopAgentWatcher();
228
- const userClaudeDir = join(homedir(), ".claude", "agents");
229
210
  const userMintoDir = join(homedir(), ".minto", "agents");
230
- const projectClaudeDir = join(getCwd(), ".claude", "agents");
231
211
  const projectMintoDir = join(getCwd(), ".minto", "agents");
232
212
  const watchDirectory = (dirPath, label) => {
233
213
  if (existsSync(dirPath)) {
@@ -248,9 +228,7 @@ async function startAgentWatcher(onChange) {
248
228
  watchers.push(watcher);
249
229
  }
250
230
  };
251
- watchDirectory(userClaudeDir, "user/.claude");
252
231
  watchDirectory(userMintoDir, "user/.minto");
253
- watchDirectory(projectClaudeDir, "project/.claude");
254
232
  watchDirectory(projectMintoDir, "project/.minto");
255
233
  }
256
234
  async function stopAgentWatcher() {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/agentLoader.ts"],
4
- "sourcesContent": ["/**\n * Agent configuration loader\n * Loads agent configurations from markdown files with YAML frontmatter.\n * Maintains compatibility with Claude Code `.claude` agent directories while\n * prioritizing Minto-specific overrides.\n */\n\nimport {\n existsSync,\n readFileSync,\n readdirSync,\n statSync,\n watch,\n FSWatcher,\n} from 'fs'\nimport { join, resolve } from 'path'\nimport { homedir } from 'os'\nimport matter from 'gray-matter'\nimport { getCwd } from './state'\nimport { memoize } from 'lodash-es'\nimport { loadAllPlugins } from './pluginLoader'\n\n// Track warned agents to avoid spam\nconst warnedAgents = new Set<string>()\n\nexport interface AgentConfig {\n agentType: string // Agent identifier (matches subagent_type)\n whenToUse: string // Description of when to use this agent\n tools: string[] | '*' // Tool permissions\n systemPrompt: string // System prompt content\n location: 'built-in' | 'user' | 'project' | 'plugin'\n color?: string // Optional UI color\n model_name?: string // Optional model override\n pluginName?: string // Source plugin name (if loaded from plugin)\n}\n\n// Built-in general-purpose agent as fallback\nconst BUILTIN_GENERAL_PURPOSE: AgentConfig = {\n agentType: 'general-purpose',\n whenToUse:\n 'General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks',\n tools: '*',\n systemPrompt: `You are a general-purpose agent. Given the user's task, use the tools available to complete it efficiently and thoroughly.\n\nWhen to use your capabilities:\n- Searching for code, configurations, and patterns across large codebases\n- Analyzing multiple files to understand system architecture \n- Investigating complex questions that require exploring many files\n- Performing multi-step research tasks\n\nGuidelines:\n- For file searches: Use Grep or Glob when you need to search broadly. Use FileRead when you know the specific file path.\n- For analysis: Start broad and narrow down. Use multiple search strategies if the first doesn't yield results.\n- Be thorough: Check multiple locations, consider different naming conventions, look for related files.\n- Complete tasks directly using your capabilities.`,\n location: 'built-in',\n}\n\n/**\n * Parse tools field from frontmatter\n */\nfunction parseTools(tools: any): string[] | '*' {\n if (!tools) return '*'\n if (tools === '*') return '*'\n if (Array.isArray(tools)) {\n // Ensure all items are strings and filter out non-strings\n const filteredTools = tools.filter(\n (t): t is string => typeof t === 'string',\n )\n return filteredTools.length > 0 ? filteredTools : '*'\n }\n if (typeof tools === 'string') {\n return [tools]\n }\n return '*'\n}\n\n/**\n * Scan a directory for agent configuration files\n */\nasync function scanAgentDirectory(\n dirPath: string,\n location: 'user' | 'project',\n): Promise<AgentConfig[]> {\n if (!existsSync(dirPath)) {\n return []\n }\n\n const agents: AgentConfig[] = []\n\n try {\n const files = readdirSync(dirPath)\n\n for (const file of files) {\n if (!file.endsWith('.md')) continue\n\n const filePath = join(dirPath, file)\n const stat = statSync(filePath)\n\n if (!stat.isFile()) continue\n\n try {\n const content = readFileSync(filePath, 'utf-8')\n const { data: frontmatter, content: body } = matter(content)\n\n // Validate required fields\n if (!frontmatter.name || !frontmatter.description) {\n console.warn(\n `Skipping ${filePath}: missing required fields (name, description)`,\n )\n continue\n }\n\n // Silently ignore deprecated 'model' field - no warnings by default\n // Only warn if MINTO_DEBUG_AGENTS environment variable is set\n if (\n frontmatter.model &&\n !frontmatter.model_name &&\n !warnedAgents.has(frontmatter.name) &&\n process.env.MINTO_DEBUG_AGENTS\n ) {\n console.warn(\n `\u26A0\uFE0F Agent ${frontmatter.name}: 'model' field is deprecated and ignored. Use 'model_name' instead, or omit to use default 'task' model.`,\n )\n warnedAgents.add(frontmatter.name)\n }\n\n // Build agent config\n const agent: AgentConfig = {\n agentType: frontmatter.name,\n whenToUse: frontmatter.description.replace(/\\\\n/g, '\\n'),\n tools: parseTools(frontmatter.tools),\n systemPrompt: body.trim(),\n location,\n ...(frontmatter.color && { color: frontmatter.color }),\n // Only use model_name field, ignore deprecated 'model' field\n ...(frontmatter.model_name && { model_name: frontmatter.model_name }),\n }\n\n agents.push(agent)\n } catch (error) {\n console.warn(`Failed to parse agent file ${filePath}:`, error)\n }\n }\n } catch (error) {\n console.warn(`Failed to scan directory ${dirPath}:`, error)\n }\n\n return agents\n}\n\n/**\n * Load agents from installed plugins\n */\nasync function loadPluginAgents(): Promise<AgentConfig[]> {\n const agents: AgentConfig[] = []\n\n try {\n const plugins = loadAllPlugins()\n\n for (const plugin of plugins) {\n // Skip disabled plugins\n if (!plugin.enabled) continue\n\n for (const pluginAgent of plugin.agents) {\n try {\n // Read the agent file to parse frontmatter and content\n const content = readFileSync(pluginAgent.filePath, 'utf-8')\n const { data: frontmatter, content: body } = matter(content)\n\n // Validate required fields\n if (!frontmatter.name || !frontmatter.description) {\n console.warn(\n `Skipping plugin agent ${pluginAgent.filePath}: missing required fields (name, description)`,\n )\n continue\n }\n\n // Warn about deprecated 'model' field if debug mode is enabled\n if (\n frontmatter.model &&\n !frontmatter.model_name &&\n !warnedAgents.has(frontmatter.name) &&\n process.env.MINTO_DEBUG_AGENTS\n ) {\n console.warn(\n `\u26A0\uFE0F Plugin agent ${frontmatter.name} (from ${plugin.manifest.name}): 'model' field is deprecated and ignored. Use 'model_name' instead, or omit to use default 'task' model.`,\n )\n warnedAgents.add(frontmatter.name)\n }\n\n // Build agent config\n const agent: AgentConfig = {\n agentType: frontmatter.name,\n whenToUse: frontmatter.description.replace(/\\\\n/g, '\\n'),\n tools: parseTools(frontmatter.tools),\n systemPrompt: body.trim(),\n location: 'plugin',\n pluginName: plugin.manifest.name,\n ...(frontmatter.color && { color: frontmatter.color }),\n // Only use model_name field, ignore deprecated 'model' field\n ...(frontmatter.model_name && {\n model_name: frontmatter.model_name,\n }),\n }\n\n agents.push(agent)\n } catch (error) {\n console.warn(\n `Failed to load plugin agent ${pluginAgent.name} from ${plugin.manifest.name}:`,\n error,\n )\n }\n }\n }\n } catch (error) {\n console.warn('Failed to load plugin agents:', error)\n }\n\n return agents\n}\n\n/**\n * Load all agent configurations\n *\n * Directory Priority (later overrides earlier):\n * 1. Built-in agents\n * 2. Plugin agents\n * 3. ~/.claude/agents (Claude Code user directory - compatible)\n * 4. ~/.minto/agents (Minto user directory - primary)\n * 5. ./.claude/agents (Claude Code project directory - compatible)\n * 6. ./.minto/agents (Minto project directory - highest priority)\n */\nasync function loadAllAgents(): Promise<{\n activeAgents: AgentConfig[]\n allAgents: AgentConfig[]\n}> {\n try {\n // Define directories in priority order\n const userClaudeDir = join(homedir(), '.claude', 'agents')\n const userMintoDir = join(homedir(), '.minto', 'agents')\n const projectClaudeDir = join(getCwd(), '.claude', 'agents')\n const projectMintoDir = join(getCwd(), '.minto', 'agents')\n\n // Load from all sources in parallel\n const [\n pluginAgents,\n userClaudeAgents,\n userMintoAgents,\n projectClaudeAgents,\n projectMintoAgents,\n ] = await Promise.all([\n loadPluginAgents(),\n scanAgentDirectory(userClaudeDir, 'user'),\n scanAgentDirectory(userMintoDir, 'user'),\n scanAgentDirectory(projectClaudeDir, 'project'),\n scanAgentDirectory(projectMintoDir, 'project'),\n ])\n\n // Built-in agents (currently just general-purpose)\n const builtinAgents = [BUILTIN_GENERAL_PURPOSE]\n\n // Apply priority override: built-in < plugin < .claude (user) < .minto (user) < .claude (project) < .minto (project)\n // Later entries override earlier ones with the same agentType\n const agentMap = new Map<string, AgentConfig>()\n\n // Add in priority order (later entries override earlier ones)\n for (const agent of builtinAgents) {\n agentMap.set(agent.agentType, agent)\n }\n for (const agent of pluginAgents) {\n agentMap.set(agent.agentType, agent)\n }\n for (const agent of userClaudeAgents) {\n agentMap.set(agent.agentType, agent)\n }\n for (const agent of userMintoAgents) {\n agentMap.set(agent.agentType, agent)\n }\n for (const agent of projectClaudeAgents) {\n agentMap.set(agent.agentType, agent)\n }\n for (const agent of projectMintoAgents) {\n agentMap.set(agent.agentType, agent)\n }\n\n const activeAgents = Array.from(agentMap.values())\n const allAgents = [\n ...builtinAgents,\n ...pluginAgents,\n ...userClaudeAgents,\n ...userMintoAgents,\n ...projectClaudeAgents,\n ...projectMintoAgents,\n ]\n\n return { activeAgents, allAgents }\n } catch (error) {\n console.error('Failed to load agents, falling back to built-in:', error)\n return {\n activeAgents: [BUILTIN_GENERAL_PURPOSE],\n allAgents: [BUILTIN_GENERAL_PURPOSE],\n }\n }\n}\n\n// Memoized version for performance\nexport const getActiveAgents = memoize(async (): Promise<AgentConfig[]> => {\n const { activeAgents } = await loadAllAgents()\n return activeAgents\n})\n\n// Get all agents (both active and overridden)\nexport const getAllAgents = memoize(async (): Promise<AgentConfig[]> => {\n const { allAgents } = await loadAllAgents()\n return allAgents\n})\n\n// Clear cache when needed\nexport function clearAgentCache() {\n getActiveAgents.cache?.clear?.()\n getAllAgents.cache?.clear?.()\n getAgentByType.cache?.clear?.()\n getAvailableAgentTypes.cache?.clear?.()\n}\n\n// Get a specific agent by type\nexport const getAgentByType = memoize(\n async (agentType: string): Promise<AgentConfig | undefined> => {\n const agents = await getActiveAgents()\n return agents.find(agent => agent.agentType === agentType)\n },\n)\n\n// Get all available agent types for validation\nexport const getAvailableAgentTypes = memoize(async (): Promise<string[]> => {\n const agents = await getActiveAgents()\n return agents.map(agent => agent.agentType)\n})\n\n// File watcher for hot reload\nlet watchers: FSWatcher[] = []\n\n/**\n * Start watching agent configuration directories for changes\n */\nexport async function startAgentWatcher(onChange?: () => void): Promise<void> {\n await stopAgentWatcher() // Clean up any existing watchers\n\n // Watch both Claude (.claude) and Minto (.minto) directories\n const userClaudeDir = join(homedir(), '.claude', 'agents')\n const userMintoDir = join(homedir(), '.minto', 'agents')\n const projectClaudeDir = join(getCwd(), '.claude', 'agents')\n const projectMintoDir = join(getCwd(), '.minto', 'agents')\n\n const watchDirectory = (dirPath: string, label: string) => {\n if (existsSync(dirPath)) {\n const watcher = watch(\n dirPath,\n { recursive: false },\n async (eventType, filename) => {\n if (filename && filename.endsWith('.md')) {\n console.log(\n `\uD83D\uDD04 Agent configuration changed in ${label}: ${filename}`,\n )\n clearAgentCache()\n // Also clear any other related caches\n getAllAgents.cache?.clear?.()\n onChange?.()\n }\n },\n )\n watchers.push(watcher)\n }\n }\n\n // Watch all directories\n watchDirectory(userClaudeDir, 'user/.claude')\n watchDirectory(userMintoDir, 'user/.minto')\n watchDirectory(projectClaudeDir, 'project/.claude')\n watchDirectory(projectMintoDir, 'project/.minto')\n}\n\n/**\n * Stop watching agent configuration directories\n */\nexport async function stopAgentWatcher(): Promise<void> {\n // FSWatcher.close() is synchronous and does not accept a callback on Node 18/20\n try {\n for (const watcher of watchers) {\n try {\n watcher.close()\n } catch (err) {\n console.error('Failed to close file watcher:', err)\n }\n }\n } finally {\n watchers = []\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Agent configuration loader\n * Loads agent configurations from markdown files with YAML frontmatter.\n * Uses only `.minto` directories for agent configuration.\n */\n\nimport {\n existsSync,\n readFileSync,\n readdirSync,\n statSync,\n watch,\n FSWatcher,\n} from 'fs'\nimport { join, resolve } from 'path'\nimport { homedir } from 'os'\nimport matter from 'gray-matter'\nimport { getCwd } from './state'\nimport { memoize } from 'lodash-es'\nimport { loadAllPlugins } from './pluginLoader'\n\n// Track warned agents to avoid spam\nconst warnedAgents = new Set<string>()\n\nexport interface AgentConfig {\n agentType: string // Agent identifier (matches subagent_type)\n whenToUse: string // Description of when to use this agent\n tools: string[] | '*' // Tool permissions\n systemPrompt: string // System prompt content\n location: 'built-in' | 'user' | 'project' | 'plugin'\n color?: string // Optional UI color\n model_name?: string // Optional model override\n pluginName?: string // Source plugin name (if loaded from plugin)\n}\n\n// Built-in general-purpose agent as fallback\nconst BUILTIN_GENERAL_PURPOSE: AgentConfig = {\n agentType: 'general-purpose',\n whenToUse:\n 'General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks',\n tools: '*',\n systemPrompt: `You are a general-purpose agent. Given the user's task, use the tools available to complete it efficiently and thoroughly.\n\nWhen to use your capabilities:\n- Searching for code, configurations, and patterns across large codebases\n- Analyzing multiple files to understand system architecture \n- Investigating complex questions that require exploring many files\n- Performing multi-step research tasks\n\nGuidelines:\n- For file searches: Use Grep or Glob when you need to search broadly. Use FileRead when you know the specific file path.\n- For analysis: Start broad and narrow down. Use multiple search strategies if the first doesn't yield results.\n- Be thorough: Check multiple locations, consider different naming conventions, look for related files.\n- Complete tasks directly using your capabilities.`,\n location: 'built-in',\n}\n\n/**\n * Parse tools field from frontmatter\n */\nfunction parseTools(tools: any): string[] | '*' {\n if (!tools) return '*'\n if (tools === '*') return '*'\n if (Array.isArray(tools)) {\n // Ensure all items are strings and filter out non-strings\n const filteredTools = tools.filter(\n (t): t is string => typeof t === 'string',\n )\n return filteredTools.length > 0 ? filteredTools : '*'\n }\n if (typeof tools === 'string') {\n return [tools]\n }\n return '*'\n}\n\n/**\n * Scan a directory for agent configuration files\n */\nasync function scanAgentDirectory(\n dirPath: string,\n location: 'user' | 'project',\n): Promise<AgentConfig[]> {\n if (!existsSync(dirPath)) {\n return []\n }\n\n const agents: AgentConfig[] = []\n\n try {\n const files = readdirSync(dirPath)\n\n for (const file of files) {\n if (!file.endsWith('.md')) continue\n\n const filePath = join(dirPath, file)\n const stat = statSync(filePath)\n\n if (!stat.isFile()) continue\n\n try {\n const content = readFileSync(filePath, 'utf-8')\n const { data: frontmatter, content: body } = matter(content)\n\n // Validate required fields\n if (!frontmatter.name || !frontmatter.description) {\n console.warn(\n `Skipping ${filePath}: missing required fields (name, description)`,\n )\n continue\n }\n\n // Silently ignore deprecated 'model' field - no warnings by default\n // Only warn if MINTO_DEBUG_AGENTS environment variable is set\n if (\n frontmatter.model &&\n !frontmatter.model_name &&\n !warnedAgents.has(frontmatter.name) &&\n process.env.MINTO_DEBUG_AGENTS\n ) {\n console.warn(\n `\u26A0\uFE0F Agent ${frontmatter.name}: 'model' field is deprecated and ignored. Use 'model_name' instead, or omit to use default 'task' model.`,\n )\n warnedAgents.add(frontmatter.name)\n }\n\n // Build agent config\n const agent: AgentConfig = {\n agentType: frontmatter.name,\n whenToUse: frontmatter.description.replace(/\\\\n/g, '\\n'),\n tools: parseTools(frontmatter.tools),\n systemPrompt: body.trim(),\n location,\n ...(frontmatter.color && { color: frontmatter.color }),\n // Only use model_name field, ignore deprecated 'model' field\n ...(frontmatter.model_name && { model_name: frontmatter.model_name }),\n }\n\n agents.push(agent)\n } catch (error) {\n console.warn(`Failed to parse agent file ${filePath}:`, error)\n }\n }\n } catch (error) {\n console.warn(`Failed to scan directory ${dirPath}:`, error)\n }\n\n return agents\n}\n\n/**\n * Load agents from installed plugins\n */\nasync function loadPluginAgents(): Promise<AgentConfig[]> {\n const agents: AgentConfig[] = []\n\n try {\n const plugins = loadAllPlugins()\n\n for (const plugin of plugins) {\n // Skip disabled plugins\n if (!plugin.enabled) continue\n\n for (const pluginAgent of plugin.agents) {\n try {\n // Read the agent file to parse frontmatter and content\n const content = readFileSync(pluginAgent.filePath, 'utf-8')\n const { data: frontmatter, content: body } = matter(content)\n\n // Validate required fields\n if (!frontmatter.name || !frontmatter.description) {\n console.warn(\n `Skipping plugin agent ${pluginAgent.filePath}: missing required fields (name, description)`,\n )\n continue\n }\n\n // Warn about deprecated 'model' field if debug mode is enabled\n if (\n frontmatter.model &&\n !frontmatter.model_name &&\n !warnedAgents.has(frontmatter.name) &&\n process.env.MINTO_DEBUG_AGENTS\n ) {\n console.warn(\n `\u26A0\uFE0F Plugin agent ${frontmatter.name} (from ${plugin.manifest.name}): 'model' field is deprecated and ignored. Use 'model_name' instead, or omit to use default 'task' model.`,\n )\n warnedAgents.add(frontmatter.name)\n }\n\n // Build agent config\n const agent: AgentConfig = {\n agentType: frontmatter.name,\n whenToUse: frontmatter.description.replace(/\\\\n/g, '\\n'),\n tools: parseTools(frontmatter.tools),\n systemPrompt: body.trim(),\n location: 'plugin',\n pluginName: plugin.manifest.name,\n ...(frontmatter.color && { color: frontmatter.color }),\n // Only use model_name field, ignore deprecated 'model' field\n ...(frontmatter.model_name && {\n model_name: frontmatter.model_name,\n }),\n }\n\n agents.push(agent)\n } catch (error) {\n console.warn(\n `Failed to load plugin agent ${pluginAgent.name} from ${plugin.manifest.name}:`,\n error,\n )\n }\n }\n }\n } catch (error) {\n console.warn('Failed to load plugin agents:', error)\n }\n\n return agents\n}\n\n/**\n * Load all agent configurations\n *\n * Directory Priority (later overrides earlier):\n * 1. Built-in agents\n * 2. Plugin agents\n * 3. ~/.minto/agents (user directory)\n * 4. ./.minto/agents (project directory - highest priority)\n */\nasync function loadAllAgents(): Promise<{\n activeAgents: AgentConfig[]\n allAgents: AgentConfig[]\n}> {\n try {\n // Define directories in priority order\n const userMintoDir = join(homedir(), '.minto', 'agents')\n const projectMintoDir = join(getCwd(), '.minto', 'agents')\n\n // Load from all sources in parallel\n const [pluginAgents, userMintoAgents, projectMintoAgents] =\n await Promise.all([\n loadPluginAgents(),\n scanAgentDirectory(userMintoDir, 'user'),\n scanAgentDirectory(projectMintoDir, 'project'),\n ])\n\n // Built-in agents (currently just general-purpose)\n const builtinAgents = [BUILTIN_GENERAL_PURPOSE]\n\n // Apply priority override: built-in < plugin < user < project\n // Later entries override earlier ones with the same agentType\n const agentMap = new Map<string, AgentConfig>()\n\n // Add in priority order (later entries override earlier ones)\n for (const agent of builtinAgents) {\n agentMap.set(agent.agentType, agent)\n }\n for (const agent of pluginAgents) {\n agentMap.set(agent.agentType, agent)\n }\n for (const agent of userMintoAgents) {\n agentMap.set(agent.agentType, agent)\n }\n for (const agent of projectMintoAgents) {\n agentMap.set(agent.agentType, agent)\n }\n\n const activeAgents = Array.from(agentMap.values())\n const allAgents = [\n ...builtinAgents,\n ...pluginAgents,\n ...userMintoAgents,\n ...projectMintoAgents,\n ]\n\n return { activeAgents, allAgents }\n } catch (error) {\n console.error('Failed to load agents, falling back to built-in:', error)\n return {\n activeAgents: [BUILTIN_GENERAL_PURPOSE],\n allAgents: [BUILTIN_GENERAL_PURPOSE],\n }\n }\n}\n\n// Memoized version for performance\nexport const getActiveAgents = memoize(async (): Promise<AgentConfig[]> => {\n const { activeAgents } = await loadAllAgents()\n return activeAgents\n})\n\n// Get all agents (both active and overridden)\nexport const getAllAgents = memoize(async (): Promise<AgentConfig[]> => {\n const { allAgents } = await loadAllAgents()\n return allAgents\n})\n\n// Clear cache when needed\nexport function clearAgentCache() {\n getActiveAgents.cache?.clear?.()\n getAllAgents.cache?.clear?.()\n getAgentByType.cache?.clear?.()\n getAvailableAgentTypes.cache?.clear?.()\n}\n\n// Get a specific agent by type\nexport const getAgentByType = memoize(\n async (agentType: string): Promise<AgentConfig | undefined> => {\n const agents = await getActiveAgents()\n return agents.find(agent => agent.agentType === agentType)\n },\n)\n\n// Get all available agent types for validation\nexport const getAvailableAgentTypes = memoize(async (): Promise<string[]> => {\n const agents = await getActiveAgents()\n return agents.map(agent => agent.agentType)\n})\n\n// File watcher for hot reload\nlet watchers: FSWatcher[] = []\n\n/**\n * Start watching agent configuration directories for changes\n */\nexport async function startAgentWatcher(onChange?: () => void): Promise<void> {\n await stopAgentWatcher() // Clean up any existing watchers\n\n // Watch .minto directories only\n const userMintoDir = join(homedir(), '.minto', 'agents')\n const projectMintoDir = join(getCwd(), '.minto', 'agents')\n\n const watchDirectory = (dirPath: string, label: string) => {\n if (existsSync(dirPath)) {\n const watcher = watch(\n dirPath,\n { recursive: false },\n async (eventType, filename) => {\n if (filename && filename.endsWith('.md')) {\n console.log(\n `\uD83D\uDD04 Agent configuration changed in ${label}: ${filename}`,\n )\n clearAgentCache()\n // Also clear any other related caches\n getAllAgents.cache?.clear?.()\n onChange?.()\n }\n },\n )\n watchers.push(watcher)\n }\n }\n\n // Watch directories\n watchDirectory(userMintoDir, 'user/.minto')\n watchDirectory(projectMintoDir, 'project/.minto')\n}\n\n/**\n * Stop watching agent configuration directories\n */\nexport async function stopAgentWatcher(): Promise<void> {\n // FSWatcher.close() is synchronous and does not accept a callback on Node 18/20\n try {\n for (const watcher of watchers) {\n try {\n watcher.close()\n } catch (err) {\n console.error('Failed to close file watcher:', err)\n }\n }\n } finally {\n watchers = []\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }