@within-7/minto 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (487) hide show
  1. package/cli.js +155 -37
  2. package/dist/Tool.js +38 -0
  3. package/dist/Tool.js.map +3 -3
  4. package/dist/commands/agents/AgentsCommand.js +52 -26
  5. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  6. package/dist/commands/agents/constants.js +1 -1
  7. package/dist/commands/agents/constants.js.map +1 -1
  8. package/dist/commands/agents/index.js +1 -1
  9. package/dist/commands/bug.js +74 -7
  10. package/dist/commands/bug.js.map +3 -3
  11. package/dist/commands/clear.js +3 -0
  12. package/dist/commands/clear.js.map +2 -2
  13. package/dist/commands/compact.js +37 -0
  14. package/dist/commands/compact.js.map +2 -2
  15. package/dist/commands/context.js +84 -0
  16. package/dist/commands/context.js.map +7 -0
  17. package/dist/commands/ctx_viz.js +18 -10
  18. package/dist/commands/ctx_viz.js.map +2 -2
  19. package/dist/commands/doctor.js +158 -12
  20. package/dist/commands/doctor.js.map +2 -2
  21. package/dist/commands/export.js +156 -0
  22. package/dist/commands/export.js.map +7 -0
  23. package/dist/commands/mcp-interactive.js +21 -12
  24. package/dist/commands/mcp-interactive.js.map +2 -2
  25. package/dist/commands/model.js +6 -5
  26. package/dist/commands/model.js.map +2 -2
  27. package/dist/commands/permissions.js +86 -0
  28. package/dist/commands/permissions.js.map +7 -0
  29. package/dist/commands/quit.js +3 -1
  30. package/dist/commands/quit.js.map +2 -2
  31. package/dist/commands/sandbox.js +104 -0
  32. package/dist/commands/sandbox.js.map +7 -0
  33. package/dist/commands/status.js +58 -0
  34. package/dist/commands/status.js.map +7 -0
  35. package/dist/commands/tasks.js +108 -0
  36. package/dist/commands/tasks.js.map +7 -0
  37. package/dist/commands/todos.js +123 -0
  38. package/dist/commands/todos.js.map +7 -0
  39. package/dist/commands.js +20 -2
  40. package/dist/commands.js.map +2 -2
  41. package/dist/components/AgentThinkingBlock.js +10 -18
  42. package/dist/components/AgentThinkingBlock.js.map +2 -2
  43. package/dist/components/BackgroundTasksPanel.js +78 -29
  44. package/dist/components/BackgroundTasksPanel.js.map +2 -2
  45. package/dist/components/BashStreamingProgress.js +24 -0
  46. package/dist/components/BashStreamingProgress.js.map +7 -0
  47. package/dist/components/CollapsibleHint.js +14 -0
  48. package/dist/components/CollapsibleHint.js.map +7 -0
  49. package/dist/components/FileEditToolUpdatedMessage.js +1 -1
  50. package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
  51. package/dist/components/HotkeyHelpPanel.js +137 -0
  52. package/dist/components/HotkeyHelpPanel.js.map +7 -0
  53. package/dist/components/Logo.js +5 -5
  54. package/dist/components/Logo.js.map +2 -2
  55. package/dist/components/Message.js +23 -7
  56. package/dist/components/Message.js.map +3 -3
  57. package/dist/components/ModelConfig.js +16 -3
  58. package/dist/components/ModelConfig.js.map +2 -2
  59. package/dist/components/ModelListManager.js +3 -3
  60. package/dist/components/ModelListManager.js.map +2 -2
  61. package/dist/components/ModelSelector/ModelSelector.js +1 -1
  62. package/dist/components/Onboarding.js +19 -14
  63. package/dist/components/Onboarding.js.map +2 -2
  64. package/dist/components/ProgressBar.js +74 -0
  65. package/dist/components/ProgressBar.js.map +7 -0
  66. package/dist/components/PromptInput.js +156 -46
  67. package/dist/components/PromptInput.js.map +2 -2
  68. package/dist/components/RequestStatusIndicator.js +194 -0
  69. package/dist/components/RequestStatusIndicator.js.map +7 -0
  70. package/dist/components/Spinner.js +92 -27
  71. package/dist/components/Spinner.js.map +2 -2
  72. package/dist/components/SpinnerSymbol.js +21 -27
  73. package/dist/components/SpinnerSymbol.js.map +2 -2
  74. package/dist/components/StreamingBashOutput.js +9 -8
  75. package/dist/components/StreamingBashOutput.js.map +2 -2
  76. package/dist/components/SubagentBlock.js +1 -1
  77. package/dist/components/SubagentBlock.js.map +1 -1
  78. package/dist/components/SubagentProgress.js +10 -11
  79. package/dist/components/SubagentProgress.js.map +2 -2
  80. package/dist/components/TaskCard.js +16 -13
  81. package/dist/components/TaskCard.js.map +2 -2
  82. package/dist/components/TodoChangeBlock.js +1 -1
  83. package/dist/components/TodoChangeBlock.js.map +2 -2
  84. package/dist/components/TodoPanel.js +120 -29
  85. package/dist/components/TodoPanel.js.map +3 -3
  86. package/dist/components/TokenCounter.js +74 -0
  87. package/dist/components/TokenCounter.js.map +7 -0
  88. package/dist/components/TokenWarning.js +2 -1
  89. package/dist/components/TokenWarning.js.map +2 -2
  90. package/dist/components/TreeConnector.js +25 -0
  91. package/dist/components/TreeConnector.js.map +7 -0
  92. package/dist/components/TurnCompletionIndicator.js +18 -0
  93. package/dist/components/TurnCompletionIndicator.js.map +7 -0
  94. package/dist/components/messages/AssistantTextMessage.js +5 -2
  95. package/dist/components/messages/AssistantTextMessage.js.map +2 -2
  96. package/dist/components/messages/AssistantThinkingMessage.js +18 -3
  97. package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
  98. package/dist/components/messages/AssistantToolUseMessage.js +11 -8
  99. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  100. package/dist/components/messages/GroupRenderer.js +53 -0
  101. package/dist/components/messages/GroupRenderer.js.map +7 -0
  102. package/dist/components/messages/NestedTasksPreview.js +12 -0
  103. package/dist/components/messages/NestedTasksPreview.js.map +7 -0
  104. package/dist/components/messages/ParallelTasksGroupView.js +92 -0
  105. package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
  106. package/dist/components/messages/TaskInModuleView.js +198 -0
  107. package/dist/components/messages/TaskInModuleView.js.map +7 -0
  108. package/dist/components/messages/TaskOutputContent.js +53 -0
  109. package/dist/components/messages/TaskOutputContent.js.map +7 -0
  110. package/dist/components/messages/UserPromptMessage.js +1 -1
  111. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  112. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
  113. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
  114. package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
  115. package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
  116. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
  117. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
  118. package/dist/constants/colors.js +48 -0
  119. package/dist/constants/colors.js.map +2 -2
  120. package/dist/constants/formatRules.js +102 -0
  121. package/dist/constants/formatRules.js.map +7 -0
  122. package/dist/constants/prompts.js +12 -34
  123. package/dist/constants/prompts.js.map +2 -2
  124. package/dist/constants/symbols.js +64 -6
  125. package/dist/constants/symbols.js.map +2 -2
  126. package/dist/constants/timing.js +5 -0
  127. package/dist/constants/timing.js.map +2 -2
  128. package/dist/core/config/defaults.js +84 -0
  129. package/dist/core/config/defaults.js.map +7 -0
  130. package/dist/core/config/index.js +111 -0
  131. package/dist/core/config/index.js.map +7 -0
  132. package/dist/core/config/loader.js +221 -0
  133. package/dist/core/config/loader.js.map +7 -0
  134. package/dist/core/config/migrations.js +128 -0
  135. package/dist/core/config/migrations.js.map +7 -0
  136. package/dist/core/config/schema.js +178 -0
  137. package/dist/core/config/schema.js.map +7 -0
  138. package/dist/core/costTracker.js +138 -0
  139. package/dist/core/costTracker.js.map +7 -0
  140. package/dist/core/index.js +5 -0
  141. package/dist/core/index.js.map +7 -0
  142. package/dist/core/permissions/auditLog.js +204 -0
  143. package/dist/core/permissions/auditLog.js.map +7 -0
  144. package/dist/core/permissions/engine/index.js +3 -0
  145. package/dist/core/permissions/engine/index.js.map +7 -0
  146. package/dist/core/permissions/engine/permissionEngine.js +106 -0
  147. package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
  148. package/dist/core/permissions/engine/types.js +1 -0
  149. package/dist/core/permissions/engine/types.js.map +7 -0
  150. package/dist/core/permissions/index.js +84 -0
  151. package/dist/core/permissions/index.js.map +7 -0
  152. package/dist/core/permissions/ruleEngine.js +259 -0
  153. package/dist/core/permissions/ruleEngine.js.map +7 -0
  154. package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
  155. package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
  156. package/dist/core/permissions/rules/autoEscalationRule.js +291 -0
  157. package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
  158. package/dist/core/permissions/rules/index.js +46 -0
  159. package/dist/core/permissions/rules/index.js.map +7 -0
  160. package/dist/core/permissions/rules/planModeRule.js +55 -0
  161. package/dist/core/permissions/rules/planModeRule.js.map +7 -0
  162. package/dist/core/permissions/rules/projectBoundaryRule.js +168 -0
  163. package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
  164. package/dist/core/permissions/rules/safeModeRule.js +65 -0
  165. package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
  166. package/dist/core/permissions/rules/sensitivePathsRule.js +340 -0
  167. package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
  168. package/dist/core/permissions/types.js +127 -0
  169. package/dist/core/permissions/types.js.map +7 -0
  170. package/dist/core/tools/executor.js +143 -0
  171. package/dist/core/tools/executor.js.map +7 -0
  172. package/dist/core/tools/index.js +15 -0
  173. package/dist/core/tools/index.js.map +7 -0
  174. package/dist/core/tools/registry.js +183 -0
  175. package/dist/core/tools/registry.js.map +7 -0
  176. package/dist/core/tools/types.js +1 -0
  177. package/dist/core/tools/types.js.map +7 -0
  178. package/dist/cost-tracker.js +23 -15
  179. package/dist/cost-tracker.js.map +2 -2
  180. package/dist/entrypoints/cli.js +43 -43
  181. package/dist/entrypoints/cli.js.map +2 -2
  182. package/dist/entrypoints/mcp.js +12 -4
  183. package/dist/entrypoints/mcp.js.map +2 -2
  184. package/dist/history.js +14 -3
  185. package/dist/history.js.map +2 -2
  186. package/dist/hooks/useAgentTranscripts.js +116 -0
  187. package/dist/hooks/useAgentTranscripts.js.map +7 -0
  188. package/dist/hooks/useAnimationSync.js +53 -0
  189. package/dist/hooks/useAnimationSync.js.map +7 -0
  190. package/dist/hooks/useArrowKeyHistory.js +4 -2
  191. package/dist/hooks/useArrowKeyHistory.js.map +2 -2
  192. package/dist/hooks/useCanUseTool.js +3 -1
  193. package/dist/hooks/useCanUseTool.js.map +2 -2
  194. package/dist/hooks/useCancelRequest.js +4 -1
  195. package/dist/hooks/useCancelRequest.js.map +2 -2
  196. package/dist/hooks/useExitOnCtrlCD.js +9 -5
  197. package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
  198. package/dist/hooks/useHookStatus.js +40 -0
  199. package/dist/hooks/useHookStatus.js.map +7 -0
  200. package/dist/hooks/useLogMessages.js +17 -1
  201. package/dist/hooks/useLogMessages.js.map +2 -2
  202. package/dist/hooks/useMessageGroups.js +43 -0
  203. package/dist/hooks/useMessageGroups.js.map +7 -0
  204. package/dist/hooks/useTerminalSize.js +62 -6
  205. package/dist/hooks/useTerminalSize.js.map +2 -2
  206. package/dist/hooks/useUnifiedCompletion.js +69 -0
  207. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  208. package/dist/i18n/index.js +109 -0
  209. package/dist/i18n/index.js.map +7 -0
  210. package/dist/i18n/locales/en.js +347 -0
  211. package/dist/i18n/locales/en.js.map +7 -0
  212. package/dist/i18n/locales/index.js +7 -0
  213. package/dist/i18n/locales/index.js.map +7 -0
  214. package/dist/i18n/locales/zh-CN.js +347 -0
  215. package/dist/i18n/locales/zh-CN.js.map +7 -0
  216. package/dist/i18n/types.js +8 -0
  217. package/dist/i18n/types.js.map +7 -0
  218. package/dist/query.js +175 -17
  219. package/dist/query.js.map +3 -3
  220. package/dist/screens/REPL.js +501 -192
  221. package/dist/screens/REPL.js.map +3 -3
  222. package/dist/services/adapters/chatCompletions.js +3 -1
  223. package/dist/services/adapters/chatCompletions.js.map +2 -2
  224. package/dist/services/adapters/messageNormalizer.js +354 -0
  225. package/dist/services/adapters/messageNormalizer.js.map +7 -0
  226. package/dist/services/adapters/responsesAPI.js +6 -3
  227. package/dist/services/adapters/responsesAPI.js.map +2 -2
  228. package/dist/services/checkpointManager.js +386 -0
  229. package/dist/services/checkpointManager.js.map +7 -0
  230. package/dist/services/claude.js +138 -11
  231. package/dist/services/claude.js.map +3 -3
  232. package/dist/services/compressionService.js +50 -1
  233. package/dist/services/compressionService.js.map +2 -2
  234. package/dist/services/contextMonitor.js +162 -0
  235. package/dist/services/contextMonitor.js.map +7 -0
  236. package/dist/services/customCommands.js +60 -41
  237. package/dist/services/customCommands.js.map +2 -2
  238. package/dist/services/hookExecutor.js +173 -1
  239. package/dist/services/hookExecutor.js.map +2 -2
  240. package/dist/services/intelligentCompactor.js +281 -0
  241. package/dist/services/intelligentCompactor.js.map +7 -0
  242. package/dist/services/lspConfig.js +109 -0
  243. package/dist/services/lspConfig.js.map +7 -0
  244. package/dist/services/mcpClient.js +273 -34
  245. package/dist/services/mcpClient.js.map +2 -2
  246. package/dist/services/modelOrchestrator.js +310 -0
  247. package/dist/services/modelOrchestrator.js.map +7 -0
  248. package/dist/services/openai.js +8 -1
  249. package/dist/services/openai.js.map +2 -2
  250. package/dist/services/outputStyles.js +138 -0
  251. package/dist/services/outputStyles.js.map +7 -0
  252. package/dist/services/plugins/index.js +5 -0
  253. package/dist/services/plugins/index.js.map +7 -0
  254. package/dist/services/plugins/lspServers.js +188 -0
  255. package/dist/services/plugins/lspServers.js.map +7 -0
  256. package/dist/services/plugins/pluginRuntime.js +229 -0
  257. package/dist/services/plugins/pluginRuntime.js.map +7 -0
  258. package/dist/services/plugins/pluginValidation.js +219 -0
  259. package/dist/services/plugins/pluginValidation.js.map +7 -0
  260. package/dist/services/plugins/skillMarketplace.js +556 -0
  261. package/dist/services/plugins/skillMarketplace.js.map +7 -0
  262. package/dist/services/responseStateManager.js +37 -3
  263. package/dist/services/responseStateManager.js.map +2 -2
  264. package/dist/services/sandbox/filesystemBoundary.js +300 -0
  265. package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
  266. package/dist/services/sandbox/index.js +14 -0
  267. package/dist/services/sandbox/index.js.map +7 -0
  268. package/dist/services/sandbox/networkProxy.js +293 -0
  269. package/dist/services/sandbox/networkProxy.js.map +7 -0
  270. package/dist/services/sandbox/sandboxController.js +574 -0
  271. package/dist/services/sandbox/sandboxController.js.map +7 -0
  272. package/dist/services/sandbox/types.js +50 -0
  273. package/dist/services/sandbox/types.js.map +7 -0
  274. package/dist/services/sessionMemory.js +266 -0
  275. package/dist/services/sessionMemory.js.map +7 -0
  276. package/dist/services/taskRouter.js +324 -0
  277. package/dist/services/taskRouter.js.map +7 -0
  278. package/dist/tools/ArchitectTool/ArchitectTool.js +10 -3
  279. package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
  280. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -0
  281. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  282. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +8 -1
  283. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
  284. package/dist/tools/BaseTool.js +72 -0
  285. package/dist/tools/BaseTool.js.map +7 -0
  286. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
  287. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
  288. package/dist/tools/BashTool/BashTool.js +60 -3
  289. package/dist/tools/BashTool/BashTool.js.map +2 -2
  290. package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
  291. package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
  292. package/dist/tools/BashTool/OutputLine.js +54 -0
  293. package/dist/tools/BashTool/OutputLine.js.map +2 -2
  294. package/dist/tools/BashTool/prompt.js +192 -3
  295. package/dist/tools/BashTool/prompt.js.map +2 -2
  296. package/dist/tools/FileEditTool/FileEditTool.js +29 -4
  297. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  298. package/dist/tools/FileReadTool/FileReadTool.js +23 -4
  299. package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
  300. package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
  301. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  302. package/dist/tools/GlobTool/GlobTool.js +14 -3
  303. package/dist/tools/GlobTool/GlobTool.js.map +2 -2
  304. package/dist/tools/GrepTool/GrepTool.js +41 -7
  305. package/dist/tools/GrepTool/GrepTool.js.map +2 -2
  306. package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
  307. package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
  308. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
  309. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
  310. package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
  311. package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
  312. package/dist/tools/LspTool/LspTool.js +664 -0
  313. package/dist/tools/LspTool/LspTool.js.map +7 -0
  314. package/dist/tools/LspTool/prompt.js +27 -0
  315. package/dist/tools/LspTool/prompt.js.map +7 -0
  316. package/dist/tools/MCPTool/MCPTool.js +11 -4
  317. package/dist/tools/MCPTool/MCPTool.js.map +2 -2
  318. package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
  319. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  320. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
  321. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  322. package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
  323. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  324. package/dist/tools/NotebookEditTool/NotebookEditTool.js +5 -1
  325. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  326. package/dist/tools/NotebookReadTool/NotebookReadTool.js +8 -4
  327. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
  328. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +74 -0
  329. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
  330. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +108 -0
  331. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
  332. package/dist/tools/PlanModeTool/prompt.js +94 -0
  333. package/dist/tools/PlanModeTool/prompt.js.map +7 -0
  334. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
  335. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
  336. package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
  337. package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
  338. package/dist/tools/SkillTool/SkillTool.js +14 -3
  339. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  340. package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
  341. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
  342. package/dist/tools/SlashCommandTool/prompt.js +35 -0
  343. package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
  344. package/dist/tools/TaskOutputTool/TaskOutputTool.js +189 -0
  345. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
  346. package/dist/tools/TaskOutputTool/prompt.js +15 -0
  347. package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
  348. package/dist/tools/TaskTool/TaskTool.js +321 -146
  349. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  350. package/dist/tools/TaskTool/prompt.js.map +2 -2
  351. package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -73
  352. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
  353. package/dist/tools/URLFetcherTool/URLFetcherTool.js +7 -1
  354. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
  355. package/dist/tools/URLFetcherTool/cache.js +55 -8
  356. package/dist/tools/URLFetcherTool/cache.js.map +2 -2
  357. package/dist/tools/WebSearchTool/WebSearchTool.js +6 -1
  358. package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
  359. package/dist/tools.js +31 -2
  360. package/dist/tools.js.map +2 -2
  361. package/dist/types/hooks.js +4 -0
  362. package/dist/types/hooks.js.map +2 -2
  363. package/dist/types/marketplace.js.map +2 -2
  364. package/dist/types/messageGroup.js +36 -0
  365. package/dist/types/messageGroup.js.map +7 -0
  366. package/dist/types/plugin.js.map +2 -2
  367. package/dist/types/thinking.js +1 -0
  368. package/dist/types/thinking.js.map +7 -0
  369. package/dist/utils/BackgroundShellManager.js +136 -39
  370. package/dist/utils/BackgroundShellManager.js.map +2 -2
  371. package/dist/utils/MessageBatchBuffer.js +102 -0
  372. package/dist/utils/MessageBatchBuffer.js.map +7 -0
  373. package/dist/utils/PersistentShell.js +151 -1
  374. package/dist/utils/PersistentShell.js.map +2 -2
  375. package/dist/utils/agentLoader.js +1 -23
  376. package/dist/utils/agentLoader.js.map +2 -2
  377. package/dist/utils/agentTranscripts.js +641 -0
  378. package/dist/utils/agentTranscripts.js.map +7 -0
  379. package/dist/utils/animationManager.js +213 -0
  380. package/dist/utils/animationManager.js.map +7 -0
  381. package/dist/utils/animationSync.js +110 -0
  382. package/dist/utils/animationSync.js.map +7 -0
  383. package/dist/utils/asyncFile.js +215 -0
  384. package/dist/utils/asyncFile.js.map +7 -0
  385. package/dist/utils/backgroundAgentManager.js +231 -0
  386. package/dist/utils/backgroundAgentManager.js.map +7 -0
  387. package/dist/utils/config.js +63 -7
  388. package/dist/utils/config.js.map +2 -2
  389. package/dist/utils/conversationRecovery.js +19 -0
  390. package/dist/utils/conversationRecovery.js.map +2 -2
  391. package/dist/utils/exit.js +73 -0
  392. package/dist/utils/exit.js.map +7 -0
  393. package/dist/utils/format.js +73 -5
  394. package/dist/utils/format.js.map +2 -2
  395. package/dist/utils/generators.js +76 -6
  396. package/dist/utils/generators.js.map +2 -2
  397. package/dist/utils/globalErrorHandler.js +149 -0
  398. package/dist/utils/globalErrorHandler.js.map +7 -0
  399. package/dist/utils/groupHandlers/index.js +8 -0
  400. package/dist/utils/groupHandlers/index.js.map +7 -0
  401. package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
  402. package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
  403. package/dist/utils/groupHandlers/taskHandler.js +104 -0
  404. package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
  405. package/dist/utils/groupHandlers/types.js +1 -0
  406. package/dist/utils/groupHandlers/types.js.map +7 -0
  407. package/dist/utils/logRotation.js +224 -0
  408. package/dist/utils/logRotation.js.map +7 -0
  409. package/dist/utils/marketplaceManager.js +3 -5
  410. package/dist/utils/marketplaceManager.js.map +2 -2
  411. package/dist/utils/memSafety.js +264 -0
  412. package/dist/utils/memSafety.js.map +7 -0
  413. package/dist/utils/messageGroupManager.js +274 -0
  414. package/dist/utils/messageGroupManager.js.map +7 -0
  415. package/dist/utils/messages.js +13 -4
  416. package/dist/utils/messages.js.map +2 -2
  417. package/dist/utils/model.js +119 -15
  418. package/dist/utils/model.js.map +3 -3
  419. package/dist/utils/permissions/filesystem.js +157 -5
  420. package/dist/utils/permissions/filesystem.js.map +2 -2
  421. package/dist/utils/plan/planMode.js +143 -0
  422. package/dist/utils/plan/planMode.js.map +7 -0
  423. package/dist/utils/pluginLoader.js +17 -21
  424. package/dist/utils/pluginLoader.js.map +2 -2
  425. package/dist/utils/ripgrep.js +55 -2
  426. package/dist/utils/ripgrep.js.map +2 -2
  427. package/dist/utils/sanitizeInput.js +32 -0
  428. package/dist/utils/sanitizeInput.js.map +7 -0
  429. package/dist/utils/secureKeyStorage.js +312 -0
  430. package/dist/utils/secureKeyStorage.js.map +7 -0
  431. package/dist/utils/session/sessionPlugins.js +67 -0
  432. package/dist/utils/session/sessionPlugins.js.map +7 -0
  433. package/dist/utils/taskDisplayUtils.js +257 -0
  434. package/dist/utils/taskDisplayUtils.js.map +7 -0
  435. package/dist/utils/teamConfig.js +2 -1
  436. package/dist/utils/teamConfig.js.map +2 -2
  437. package/dist/utils/todoStorage.js +92 -2
  438. package/dist/utils/todoStorage.js.map +2 -2
  439. package/dist/utils/toolTimeout.js +136 -0
  440. package/dist/utils/toolTimeout.js.map +7 -0
  441. package/dist/utils/tooling/safeRender.js +115 -0
  442. package/dist/utils/tooling/safeRender.js.map +7 -0
  443. package/dist/utils/userFriendlyError.js +346 -0
  444. package/dist/utils/userFriendlyError.js.map +7 -0
  445. package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
  446. package/dist/version.js +2 -2
  447. package/dist/version.js.map +1 -1
  448. package/package.json +14 -4
  449. package/scripts/postinstall.js +128 -38
  450. package/dist/commands/agents.js +0 -2086
  451. package/dist/commands/agents.js.map +0 -7
  452. package/dist/commands/build.js +0 -74
  453. package/dist/commands/build.js.map +0 -7
  454. package/dist/commands/compression.js +0 -57
  455. package/dist/commands/compression.js.map +0 -7
  456. package/dist/commands/listen.js +0 -37
  457. package/dist/commands/listen.js.map +0 -7
  458. package/dist/commands/login.js +0 -37
  459. package/dist/commands/login.js.map +0 -7
  460. package/dist/commands/logout.js +0 -33
  461. package/dist/commands/logout.js.map +0 -7
  462. package/dist/commands/mcp.js +0 -40
  463. package/dist/commands/mcp.js.map +0 -7
  464. package/dist/commands/mcp_refresh.js +0 -40
  465. package/dist/commands/mcp_refresh.js.map +0 -7
  466. package/dist/commands/modelstatus.js +0 -21
  467. package/dist/commands/modelstatus.js.map +0 -7
  468. package/dist/commands/onboarding.js +0 -36
  469. package/dist/commands/onboarding.js.map +0 -7
  470. package/dist/commands/plugin-interactive.js +0 -446
  471. package/dist/commands/plugin-interactive.js.map +0 -7
  472. package/dist/commands/pr_comments.js +0 -61
  473. package/dist/commands/pr_comments.js.map +0 -7
  474. package/dist/commands/release-notes.js +0 -30
  475. package/dist/commands/release-notes.js.map +0 -7
  476. package/dist/commands/review.js +0 -51
  477. package/dist/commands/review.js.map +0 -7
  478. package/dist/components/Bug.js +0 -147
  479. package/dist/components/Bug.js.map +0 -7
  480. package/dist/components/ModelSelector.js +0 -2062
  481. package/dist/components/ModelSelector.js.map +0 -7
  482. package/dist/components/ModelStatusDisplay.js +0 -87
  483. package/dist/components/ModelStatusDisplay.js.map +0 -7
  484. package/dist/entrypoints/cli-wrapper.js +0 -61
  485. package/dist/entrypoints/cli-wrapper.js.map +0 -7
  486. package/dist/screens/Doctor.js +0 -22
  487. package/dist/screens/Doctor.js.map +0 -7
@@ -0,0 +1,312 @@
1
+ import { spawnSync } from "child_process";
2
+ import {
3
+ existsSync,
4
+ readFileSync,
5
+ writeFileSync,
6
+ mkdirSync,
7
+ unlinkSync
8
+ } from "fs";
9
+ import { join } from "path";
10
+ import { homedir, hostname, platform } from "os";
11
+ import {
12
+ createCipheriv,
13
+ createDecipheriv,
14
+ randomBytes,
15
+ scryptSync,
16
+ createHash
17
+ } from "crypto";
18
+ const SERVICE_NAME = "com.minto.cli";
19
+ const ENCRYPTED_KEYS_DIR = join(homedir(), ".minto", "secure");
20
+ const ENCRYPTED_KEYS_FILE = join(ENCRYPTED_KEYS_DIR, "keys.enc");
21
+ function isMacOSWithKeychain() {
22
+ if (platform() !== "darwin") return false;
23
+ try {
24
+ const result = spawnSync("security", ["help"], {
25
+ encoding: "utf-8",
26
+ timeout: 5e3
27
+ });
28
+ return result.status === 0 || result.status === 1;
29
+ } catch {
30
+ return false;
31
+ }
32
+ }
33
+ function getMachineKey() {
34
+ const machineId = getMachineId();
35
+ const combined = `${hostname()}-${machineId}-minto-secure-storage`;
36
+ return createHash("sha256").update(combined).digest();
37
+ }
38
+ function getMachineId() {
39
+ const sources = [
40
+ // macOS - use spawnSync instead of execSync for safety
41
+ () => {
42
+ if (platform() === "darwin") {
43
+ try {
44
+ const result = spawnSync(
45
+ "ioreg",
46
+ ["-rd1", "-c", "IOPlatformExpertDevice"],
47
+ {
48
+ encoding: "utf-8",
49
+ timeout: 5e3
50
+ }
51
+ );
52
+ if (result.status === 0 && result.stdout) {
53
+ const match = result.stdout.match(
54
+ /"IOPlatformUUID"\s*=\s*"([^"]+)"/
55
+ );
56
+ if (match) return match[1];
57
+ }
58
+ } catch {
59
+ }
60
+ }
61
+ return null;
62
+ },
63
+ // Linux - read from file directly (no shell needed)
64
+ () => {
65
+ if (platform() === "linux") {
66
+ try {
67
+ if (existsSync("/etc/machine-id")) {
68
+ return readFileSync("/etc/machine-id", "utf-8").trim();
69
+ }
70
+ if (existsSync("/var/lib/dbus/machine-id")) {
71
+ return readFileSync("/var/lib/dbus/machine-id", "utf-8").trim();
72
+ }
73
+ } catch {
74
+ }
75
+ }
76
+ return null;
77
+ },
78
+ // Fallback: use hostname hash
79
+ () => {
80
+ return createHash("sha256").update(hostname()).digest("hex").slice(0, 32);
81
+ }
82
+ ];
83
+ for (const source of sources) {
84
+ const id = source();
85
+ if (id) return id;
86
+ }
87
+ return "minto-default-machine-id";
88
+ }
89
+ function encrypt(data, key) {
90
+ const iv = randomBytes(16);
91
+ const salt = randomBytes(32);
92
+ const derivedKey = scryptSync(key, salt, 32);
93
+ const cipher = createCipheriv("aes-256-gcm", derivedKey, iv);
94
+ const encrypted = Buffer.concat([
95
+ cipher.update(data, "utf-8"),
96
+ cipher.final()
97
+ ]);
98
+ const authTag = cipher.getAuthTag();
99
+ return [
100
+ salt.toString("base64"),
101
+ iv.toString("base64"),
102
+ authTag.toString("base64"),
103
+ encrypted.toString("base64")
104
+ ].join(":");
105
+ }
106
+ function decrypt(encryptedData, key) {
107
+ const parts = encryptedData.split(":");
108
+ if (parts.length !== 4) {
109
+ throw new Error("Invalid encrypted data format");
110
+ }
111
+ const [saltB64, ivB64, authTagB64, encryptedB64] = parts;
112
+ const salt = Buffer.from(saltB64, "base64");
113
+ const iv = Buffer.from(ivB64, "base64");
114
+ const authTag = Buffer.from(authTagB64, "base64");
115
+ const encrypted = Buffer.from(encryptedB64, "base64");
116
+ const derivedKey = scryptSync(key, salt, 32);
117
+ const decipher = createDecipheriv("aes-256-gcm", derivedKey, iv);
118
+ decipher.setAuthTag(authTag);
119
+ return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString(
120
+ "utf-8"
121
+ );
122
+ }
123
+ function storeInKeychain(keyName, value) {
124
+ try {
125
+ spawnSync(
126
+ "security",
127
+ ["delete-generic-password", "-s", SERVICE_NAME, "-a", keyName],
128
+ { timeout: 5e3 }
129
+ );
130
+ const result = spawnSync(
131
+ "security",
132
+ [
133
+ "add-generic-password",
134
+ "-s",
135
+ SERVICE_NAME,
136
+ "-a",
137
+ keyName,
138
+ "-w",
139
+ value,
140
+ "-U"
141
+ // Update if exists
142
+ ],
143
+ { timeout: 5e3 }
144
+ );
145
+ return result.status === 0;
146
+ } catch {
147
+ return false;
148
+ }
149
+ }
150
+ function getFromKeychain(keyName) {
151
+ try {
152
+ const result = spawnSync(
153
+ "security",
154
+ [
155
+ "find-generic-password",
156
+ "-s",
157
+ SERVICE_NAME,
158
+ "-a",
159
+ keyName,
160
+ "-w"
161
+ // Output password only
162
+ ],
163
+ {
164
+ encoding: "utf-8",
165
+ timeout: 5e3
166
+ }
167
+ );
168
+ if (result.status === 0 && result.stdout) {
169
+ return result.stdout.trim();
170
+ }
171
+ return null;
172
+ } catch {
173
+ return null;
174
+ }
175
+ }
176
+ function deleteFromKeychain(keyName) {
177
+ try {
178
+ const result = spawnSync(
179
+ "security",
180
+ ["delete-generic-password", "-s", SERVICE_NAME, "-a", keyName],
181
+ { timeout: 5e3 }
182
+ );
183
+ return result.status === 0;
184
+ } catch {
185
+ return false;
186
+ }
187
+ }
188
+ function loadEncryptedKeys() {
189
+ if (!existsSync(ENCRYPTED_KEYS_FILE)) {
190
+ return {};
191
+ }
192
+ try {
193
+ const encryptedContent = readFileSync(ENCRYPTED_KEYS_FILE, "utf-8");
194
+ const machineKey = getMachineKey();
195
+ const decrypted = decrypt(encryptedContent, machineKey);
196
+ return JSON.parse(decrypted);
197
+ } catch {
198
+ return {};
199
+ }
200
+ }
201
+ function saveEncryptedKeys(keys) {
202
+ if (!existsSync(ENCRYPTED_KEYS_DIR)) {
203
+ mkdirSync(ENCRYPTED_KEYS_DIR, { recursive: true, mode: 448 });
204
+ }
205
+ const machineKey = getMachineKey();
206
+ const encrypted = encrypt(JSON.stringify(keys), machineKey);
207
+ writeFileSync(ENCRYPTED_KEYS_FILE, encrypted, { mode: 384 });
208
+ }
209
+ function storeApiKey(keyName, value) {
210
+ if (!keyName || !value) {
211
+ return false;
212
+ }
213
+ if (isMacOSWithKeychain()) {
214
+ if (storeInKeychain(keyName, value)) {
215
+ return true;
216
+ }
217
+ }
218
+ try {
219
+ const keys = loadEncryptedKeys();
220
+ keys[keyName] = value;
221
+ saveEncryptedKeys(keys);
222
+ return true;
223
+ } catch {
224
+ return false;
225
+ }
226
+ }
227
+ function getApiKey(keyName) {
228
+ if (!keyName) {
229
+ return null;
230
+ }
231
+ if (isMacOSWithKeychain()) {
232
+ const value = getFromKeychain(keyName);
233
+ if (value) {
234
+ return value;
235
+ }
236
+ }
237
+ try {
238
+ const keys = loadEncryptedKeys();
239
+ return keys[keyName] || null;
240
+ } catch {
241
+ return null;
242
+ }
243
+ }
244
+ function deleteApiKey(keyName) {
245
+ if (!keyName) {
246
+ return false;
247
+ }
248
+ let success = false;
249
+ if (isMacOSWithKeychain()) {
250
+ if (deleteFromKeychain(keyName)) {
251
+ success = true;
252
+ }
253
+ }
254
+ try {
255
+ const keys = loadEncryptedKeys();
256
+ if (keys[keyName]) {
257
+ delete keys[keyName];
258
+ saveEncryptedKeys(keys);
259
+ success = true;
260
+ }
261
+ } catch {
262
+ }
263
+ return success;
264
+ }
265
+ function hasApiKey(keyName) {
266
+ return getApiKey(keyName) !== null;
267
+ }
268
+ function listApiKeyNames() {
269
+ const names = /* @__PURE__ */ new Set();
270
+ try {
271
+ const keys = loadEncryptedKeys();
272
+ for (const name of Object.keys(keys)) {
273
+ names.add(name);
274
+ }
275
+ } catch {
276
+ }
277
+ return Array.from(names);
278
+ }
279
+ function migrateApiKeyToSecure(keyName, plainTextValue) {
280
+ if (!plainTextValue) {
281
+ return false;
282
+ }
283
+ if (storeApiKey(keyName, plainTextValue)) {
284
+ return true;
285
+ }
286
+ return false;
287
+ }
288
+ function getStorageBackendInfo() {
289
+ if (isMacOSWithKeychain()) {
290
+ return { backend: "keychain", available: true };
291
+ }
292
+ return { backend: "encrypted-file", available: true };
293
+ }
294
+ function clearAllApiKeys() {
295
+ if (existsSync(ENCRYPTED_KEYS_FILE)) {
296
+ try {
297
+ unlinkSync(ENCRYPTED_KEYS_FILE);
298
+ } catch {
299
+ }
300
+ }
301
+ }
302
+ export {
303
+ clearAllApiKeys,
304
+ deleteApiKey,
305
+ getApiKey,
306
+ getStorageBackendInfo,
307
+ hasApiKey,
308
+ listApiKeyNames,
309
+ migrateApiKeyToSecure,
310
+ storeApiKey
311
+ };
312
+ //# sourceMappingURL=secureKeyStorage.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/secureKeyStorage.ts"],
4
+ "sourcesContent": ["/**\n * Secure Key Storage\n *\n * Provides secure storage for API keys using system keychain on macOS\n * and encrypted file storage on other platforms.\n *\n * Security features:\n * - Uses macOS Keychain via `security` command when available\n * - Falls back to AES-256-GCM encrypted file storage\n * - Encryption key derived from machine-specific data\n * - Keys never stored in plain text in config files\n */\n\nimport { spawnSync } from 'child_process'\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n unlinkSync,\n} from 'fs'\nimport { join } from 'path'\nimport { homedir, hostname, platform } from 'os'\nimport {\n createCipheriv,\n createDecipheriv,\n randomBytes,\n scryptSync,\n createHash,\n} from 'crypto'\n\nconst SERVICE_NAME = 'com.minto.cli'\nconst ENCRYPTED_KEYS_DIR = join(homedir(), '.minto', 'secure')\nconst ENCRYPTED_KEYS_FILE = join(ENCRYPTED_KEYS_DIR, 'keys.enc')\n\n/**\n * Check if we're running on macOS with Keychain available\n */\nfunction isMacOSWithKeychain(): boolean {\n if (platform() !== 'darwin') return false\n\n try {\n const result = spawnSync('security', ['help'], {\n encoding: 'utf-8',\n timeout: 5000,\n })\n return result.status === 0 || result.status === 1 // security help returns 1\n } catch {\n return false\n }\n}\n\n/**\n * Get machine-specific key for encryption\n * Combines hostname and a stable machine identifier\n */\nfunction getMachineKey(): Buffer {\n const machineId = getMachineId()\n const combined = `${hostname()}-${machineId}-minto-secure-storage`\n return createHash('sha256').update(combined).digest()\n}\n\n/**\n * Get a stable machine identifier using safe methods only\n */\nfunction getMachineId(): string {\n // Try to get machine ID from various sources\n const sources = [\n // macOS - use spawnSync instead of execSync for safety\n () => {\n if (platform() === 'darwin') {\n try {\n const result = spawnSync(\n 'ioreg',\n ['-rd1', '-c', 'IOPlatformExpertDevice'],\n {\n encoding: 'utf-8',\n timeout: 5000,\n },\n )\n if (result.status === 0 && result.stdout) {\n const match = result.stdout.match(\n /\"IOPlatformUUID\"\\s*=\\s*\"([^\"]+)\"/,\n )\n if (match) return match[1]\n }\n } catch {}\n }\n return null\n },\n // Linux - read from file directly (no shell needed)\n () => {\n if (platform() === 'linux') {\n try {\n if (existsSync('/etc/machine-id')) {\n return readFileSync('/etc/machine-id', 'utf-8').trim()\n }\n if (existsSync('/var/lib/dbus/machine-id')) {\n return readFileSync('/var/lib/dbus/machine-id', 'utf-8').trim()\n }\n } catch {}\n }\n return null\n },\n // Fallback: use hostname hash\n () => {\n return createHash('sha256').update(hostname()).digest('hex').slice(0, 32)\n },\n ]\n\n for (const source of sources) {\n const id = source()\n if (id) return id\n }\n\n // Should never reach here due to fallback\n return 'minto-default-machine-id'\n}\n\n/**\n * Encrypt data using AES-256-GCM\n */\nfunction encrypt(data: string, key: Buffer): string {\n const iv = randomBytes(16)\n const salt = randomBytes(32)\n const derivedKey = scryptSync(key, salt, 32)\n\n const cipher = createCipheriv('aes-256-gcm', derivedKey, iv)\n const encrypted = Buffer.concat([\n cipher.update(data, 'utf-8'),\n cipher.final(),\n ])\n const authTag = cipher.getAuthTag()\n\n // Format: salt:iv:authTag:encrypted (all base64)\n return [\n salt.toString('base64'),\n iv.toString('base64'),\n authTag.toString('base64'),\n encrypted.toString('base64'),\n ].join(':')\n}\n\n/**\n * Decrypt data using AES-256-GCM\n */\nfunction decrypt(encryptedData: string, key: Buffer): string {\n const parts = encryptedData.split(':')\n if (parts.length !== 4) {\n throw new Error('Invalid encrypted data format')\n }\n\n const [saltB64, ivB64, authTagB64, encryptedB64] = parts\n const salt = Buffer.from(saltB64, 'base64')\n const iv = Buffer.from(ivB64, 'base64')\n const authTag = Buffer.from(authTagB64, 'base64')\n const encrypted = Buffer.from(encryptedB64, 'base64')\n\n const derivedKey = scryptSync(key, salt, 32)\n const decipher = createDecipheriv('aes-256-gcm', derivedKey, iv)\n decipher.setAuthTag(authTag)\n\n return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString(\n 'utf-8',\n )\n}\n\n/**\n * Store API key in macOS Keychain\n */\nfunction storeInKeychain(keyName: string, value: string): boolean {\n try {\n // First try to delete existing entry\n spawnSync(\n 'security',\n ['delete-generic-password', '-s', SERVICE_NAME, '-a', keyName],\n { timeout: 5000 },\n )\n\n // Add new entry\n const result = spawnSync(\n 'security',\n [\n 'add-generic-password',\n '-s',\n SERVICE_NAME,\n '-a',\n keyName,\n '-w',\n value,\n '-U', // Update if exists\n ],\n { timeout: 5000 },\n )\n\n return result.status === 0\n } catch {\n return false\n }\n}\n\n/**\n * Retrieve API key from macOS Keychain\n */\nfunction getFromKeychain(keyName: string): string | null {\n try {\n const result = spawnSync(\n 'security',\n [\n 'find-generic-password',\n '-s',\n SERVICE_NAME,\n '-a',\n keyName,\n '-w', // Output password only\n ],\n {\n encoding: 'utf-8',\n timeout: 5000,\n },\n )\n\n if (result.status === 0 && result.stdout) {\n return result.stdout.trim()\n }\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Delete API key from macOS Keychain\n */\nfunction deleteFromKeychain(keyName: string): boolean {\n try {\n const result = spawnSync(\n 'security',\n ['delete-generic-password', '-s', SERVICE_NAME, '-a', keyName],\n { timeout: 5000 },\n )\n\n return result.status === 0\n } catch {\n return false\n }\n}\n\n/**\n * Load encrypted keys from file\n */\nfunction loadEncryptedKeys(): Record<string, string> {\n if (!existsSync(ENCRYPTED_KEYS_FILE)) {\n return {}\n }\n\n try {\n const encryptedContent = readFileSync(ENCRYPTED_KEYS_FILE, 'utf-8')\n const machineKey = getMachineKey()\n const decrypted = decrypt(encryptedContent, machineKey)\n return JSON.parse(decrypted)\n } catch {\n // If decryption fails (e.g., machine key changed), return empty\n return {}\n }\n}\n\n/**\n * Save encrypted keys to file\n */\nfunction saveEncryptedKeys(keys: Record<string, string>): void {\n // Ensure directory exists\n if (!existsSync(ENCRYPTED_KEYS_DIR)) {\n mkdirSync(ENCRYPTED_KEYS_DIR, { recursive: true, mode: 0o700 })\n }\n\n const machineKey = getMachineKey()\n const encrypted = encrypt(JSON.stringify(keys), machineKey)\n writeFileSync(ENCRYPTED_KEYS_FILE, encrypted, { mode: 0o600 })\n}\n\n/**\n * Store an API key securely\n */\nexport function storeApiKey(keyName: string, value: string): boolean {\n // Validate input\n if (!keyName || !value) {\n return false\n }\n\n // Try macOS Keychain first\n if (isMacOSWithKeychain()) {\n if (storeInKeychain(keyName, value)) {\n return true\n }\n }\n\n // Fall back to encrypted file storage\n try {\n const keys = loadEncryptedKeys()\n keys[keyName] = value\n saveEncryptedKeys(keys)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Retrieve an API key securely\n */\nexport function getApiKey(keyName: string): string | null {\n if (!keyName) {\n return null\n }\n\n // Try macOS Keychain first\n if (isMacOSWithKeychain()) {\n const value = getFromKeychain(keyName)\n if (value) {\n return value\n }\n }\n\n // Fall back to encrypted file storage\n try {\n const keys = loadEncryptedKeys()\n return keys[keyName] || null\n } catch {\n return null\n }\n}\n\n/**\n * Delete an API key\n */\nexport function deleteApiKey(keyName: string): boolean {\n if (!keyName) {\n return false\n }\n\n let success = false\n\n // Try macOS Keychain\n if (isMacOSWithKeychain()) {\n if (deleteFromKeychain(keyName)) {\n success = true\n }\n }\n\n // Also remove from encrypted file\n try {\n const keys = loadEncryptedKeys()\n if (keys[keyName]) {\n delete keys[keyName]\n saveEncryptedKeys(keys)\n success = true\n }\n } catch {}\n\n return success\n}\n\n/**\n * Check if an API key exists\n */\nexport function hasApiKey(keyName: string): boolean {\n return getApiKey(keyName) !== null\n}\n\n/**\n * List all stored API key names (not values)\n */\nexport function listApiKeyNames(): string[] {\n const names = new Set<string>()\n\n // From encrypted file\n try {\n const keys = loadEncryptedKeys()\n for (const name of Object.keys(keys)) {\n names.add(name)\n }\n } catch {}\n\n return Array.from(names)\n}\n\n/**\n * Migrate API key from plain text config to secure storage\n * Returns true if migration was successful or key was already secure\n */\nexport function migrateApiKeyToSecure(\n keyName: string,\n plainTextValue: string,\n): boolean {\n if (!plainTextValue) {\n return false\n }\n\n // Store in secure storage\n if (storeApiKey(keyName, plainTextValue)) {\n return true\n }\n\n return false\n}\n\n/**\n * Get storage backend info (for debugging)\n */\nexport function getStorageBackendInfo(): {\n backend: 'keychain' | 'encrypted-file'\n available: boolean\n} {\n if (isMacOSWithKeychain()) {\n return { backend: 'keychain', available: true }\n }\n return { backend: 'encrypted-file', available: true }\n}\n\n/**\n * Clear all stored API keys (use with caution)\n */\nexport function clearAllApiKeys(): void {\n // Clear encrypted file\n if (existsSync(ENCRYPTED_KEYS_FILE)) {\n try {\n unlinkSync(ENCRYPTED_KEYS_FILE)\n } catch {}\n }\n\n // Note: We don't clear Keychain entries automatically\n // as that could affect other applications\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,67 @@
1
+ let sessionPlugins = [];
2
+ function setSessionPlugins(next) {
3
+ sessionPlugins = next;
4
+ }
5
+ function getSessionPlugins() {
6
+ return sessionPlugins;
7
+ }
8
+ function clearSessionPlugins() {
9
+ sessionPlugins = [];
10
+ }
11
+ function addSessionPlugin(plugin) {
12
+ sessionPlugins = sessionPlugins.filter((p) => p.name !== plugin.name);
13
+ sessionPlugins.push(plugin);
14
+ }
15
+ function removeSessionPlugin(name) {
16
+ const initialLength = sessionPlugins.length;
17
+ sessionPlugins = sessionPlugins.filter((p) => p.name !== name);
18
+ return sessionPlugins.length < initialLength;
19
+ }
20
+ function getSessionPlugin(name) {
21
+ return sessionPlugins.find((p) => p.name === name);
22
+ }
23
+ function hasSessionPlugin(name) {
24
+ return sessionPlugins.some((p) => p.name === name);
25
+ }
26
+ function getAllPluginAgentDirs() {
27
+ return sessionPlugins.flatMap((p) => p.agentsDirs);
28
+ }
29
+ function getAllPluginCommandDirs() {
30
+ return sessionPlugins.flatMap((p) => p.commandsDirs);
31
+ }
32
+ function getAllPluginSkillDirs() {
33
+ return sessionPlugins.flatMap((p) => p.skillsDirs);
34
+ }
35
+ function getAllPluginHooksFiles() {
36
+ return sessionPlugins.flatMap((p) => p.hooksFiles);
37
+ }
38
+ function getAllPluginMcpConfigFiles() {
39
+ return sessionPlugins.flatMap((p) => p.mcpConfigFiles);
40
+ }
41
+ function getAllPluginLspConfigFiles() {
42
+ return sessionPlugins.flatMap((p) => p.lspConfigFiles);
43
+ }
44
+ function getAllPluginOutputStyleDirs() {
45
+ return sessionPlugins.flatMap((p) => p.outputStylesDirs);
46
+ }
47
+ function __resetSessionPluginsForTests() {
48
+ sessionPlugins = [];
49
+ }
50
+ export {
51
+ __resetSessionPluginsForTests,
52
+ addSessionPlugin,
53
+ clearSessionPlugins,
54
+ getAllPluginAgentDirs,
55
+ getAllPluginCommandDirs,
56
+ getAllPluginHooksFiles,
57
+ getAllPluginLspConfigFiles,
58
+ getAllPluginMcpConfigFiles,
59
+ getAllPluginOutputStyleDirs,
60
+ getAllPluginSkillDirs,
61
+ getSessionPlugin,
62
+ getSessionPlugins,
63
+ hasSessionPlugin,
64
+ removeSessionPlugin,
65
+ setSessionPlugins
66
+ };
67
+ //# sourceMappingURL=sessionPlugins.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/utils/session/sessionPlugins.ts"],
4
+ "sourcesContent": ["/**\n * Session Plugin State Management\n *\n * Manages the plugins loaded in the current session.\n * Compatible with Claude Code CLI session plugins specification.\n */\n\nimport type { SessionPlugin } from '@minto-types/plugin'\n\n/**\n * Current session plugins\n */\nlet sessionPlugins: SessionPlugin[] = []\n\n/**\n * Set the session plugins\n */\nexport function setSessionPlugins(next: SessionPlugin[]): void {\n sessionPlugins = next\n}\n\n/**\n * Get the current session plugins\n */\nexport function getSessionPlugins(): SessionPlugin[] {\n return sessionPlugins\n}\n\n/**\n * Clear all session plugins\n */\nexport function clearSessionPlugins(): void {\n sessionPlugins = []\n}\n\n/**\n * Add a single plugin to the session\n */\nexport function addSessionPlugin(plugin: SessionPlugin): void {\n // Remove existing plugin with same name if present\n sessionPlugins = sessionPlugins.filter(p => p.name !== plugin.name)\n sessionPlugins.push(plugin)\n}\n\n/**\n * Remove a plugin from the session by name\n */\nexport function removeSessionPlugin(name: string): boolean {\n const initialLength = sessionPlugins.length\n sessionPlugins = sessionPlugins.filter(p => p.name !== name)\n return sessionPlugins.length < initialLength\n}\n\n/**\n * Get a plugin by name\n */\nexport function getSessionPlugin(name: string): SessionPlugin | undefined {\n return sessionPlugins.find(p => p.name === name)\n}\n\n/**\n * Check if a plugin is loaded\n */\nexport function hasSessionPlugin(name: string): boolean {\n return sessionPlugins.some(p => p.name === name)\n}\n\n/**\n * Get all agent directories from loaded plugins\n */\nexport function getAllPluginAgentDirs(): string[] {\n return sessionPlugins.flatMap(p => p.agentsDirs)\n}\n\n/**\n * Get all command directories from loaded plugins\n */\nexport function getAllPluginCommandDirs(): string[] {\n return sessionPlugins.flatMap(p => p.commandsDirs)\n}\n\n/**\n * Get all skill directories from loaded plugins\n */\nexport function getAllPluginSkillDirs(): string[] {\n return sessionPlugins.flatMap(p => p.skillsDirs)\n}\n\n/**\n * Get all hooks files from loaded plugins\n */\nexport function getAllPluginHooksFiles(): string[] {\n return sessionPlugins.flatMap(p => p.hooksFiles)\n}\n\n/**\n * Get all MCP config files from loaded plugins\n */\nexport function getAllPluginMcpConfigFiles(): string[] {\n return sessionPlugins.flatMap(p => p.mcpConfigFiles)\n}\n\n/**\n * Get all LSP config files from loaded plugins\n */\nexport function getAllPluginLspConfigFiles(): string[] {\n return sessionPlugins.flatMap(p => p.lspConfigFiles)\n}\n\n/**\n * Get all output style directories from loaded plugins\n */\nexport function getAllPluginOutputStyleDirs(): string[] {\n return sessionPlugins.flatMap(p => p.outputStylesDirs)\n}\n\n/**\n * Reset session plugins (for testing)\n */\nexport function __resetSessionPluginsForTests(): void {\n sessionPlugins = []\n}\n"],
5
+ "mappings": "AAYA,IAAI,iBAAkC,CAAC;AAKhC,SAAS,kBAAkB,MAA6B;AAC7D,mBAAiB;AACnB;AAKO,SAAS,oBAAqC;AACnD,SAAO;AACT;AAKO,SAAS,sBAA4B;AAC1C,mBAAiB,CAAC;AACpB;AAKO,SAAS,iBAAiB,QAA6B;AAE5D,mBAAiB,eAAe,OAAO,OAAK,EAAE,SAAS,OAAO,IAAI;AAClE,iBAAe,KAAK,MAAM;AAC5B;AAKO,SAAS,oBAAoB,MAAuB;AACzD,QAAM,gBAAgB,eAAe;AACrC,mBAAiB,eAAe,OAAO,OAAK,EAAE,SAAS,IAAI;AAC3D,SAAO,eAAe,SAAS;AACjC;AAKO,SAAS,iBAAiB,MAAyC;AACxE,SAAO,eAAe,KAAK,OAAK,EAAE,SAAS,IAAI;AACjD;AAKO,SAAS,iBAAiB,MAAuB;AACtD,SAAO,eAAe,KAAK,OAAK,EAAE,SAAS,IAAI;AACjD;AAKO,SAAS,wBAAkC;AAChD,SAAO,eAAe,QAAQ,OAAK,EAAE,UAAU;AACjD;AAKO,SAAS,0BAAoC;AAClD,SAAO,eAAe,QAAQ,OAAK,EAAE,YAAY;AACnD;AAKO,SAAS,wBAAkC;AAChD,SAAO,eAAe,QAAQ,OAAK,EAAE,UAAU;AACjD;AAKO,SAAS,yBAAmC;AACjD,SAAO,eAAe,QAAQ,OAAK,EAAE,UAAU;AACjD;AAKO,SAAS,6BAAuC;AACrD,SAAO,eAAe,QAAQ,OAAK,EAAE,cAAc;AACrD;AAKO,SAAS,6BAAuC;AACrD,SAAO,eAAe,QAAQ,OAAK,EAAE,cAAc;AACrD;AAKO,SAAS,8BAAwC;AACtD,SAAO,eAAe,QAAQ,OAAK,EAAE,gBAAgB;AACvD;AAKO,SAAS,gCAAsC;AACpD,mBAAiB,CAAC;AACpB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,257 @@
1
+ import { getAgentTranscript, getAgentIdByToolUseId } from "./agentTranscripts.js";
2
+ import { SEMANTIC_COLORS } from "../constants/colors.js";
3
+ import { SYMBOLS } from "../constants/symbols.js";
4
+ function getLatestOutput(transcript) {
5
+ const messages = transcript.messages;
6
+ for (let i = messages.length - 1; i >= 0; i--) {
7
+ const msg = messages[i];
8
+ if (msg.type === "assistant") {
9
+ const content = msg.message.content;
10
+ if (!content || !Array.isArray(content)) continue;
11
+ const textBlock = content.find((b) => b.type === "text");
12
+ if (textBlock && "text" in textBlock) {
13
+ return textBlock.text;
14
+ }
15
+ }
16
+ }
17
+ return "";
18
+ }
19
+ function getNestedTasks(transcript) {
20
+ const nested = [];
21
+ for (const msg of transcript.messages) {
22
+ if (msg.type === "assistant") {
23
+ const content = msg.message.content;
24
+ if (!content || !Array.isArray(content)) continue;
25
+ for (const block of content) {
26
+ if (block.type === "tool_use" && block.name === "Task") {
27
+ const toolUse = block;
28
+ const nestedAgentId = getAgentIdByToolUseId(toolUse.id);
29
+ if (nestedAgentId) {
30
+ const nestedTranscript = getAgentTranscript(nestedAgentId);
31
+ if (nestedTranscript) {
32
+ nested.push(nestedTranscript);
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ return nested;
40
+ }
41
+ function truncate(text, maxLength) {
42
+ if (!text) return "";
43
+ const cleaned = text.trim().replace(/\n+/g, " ").replace(/\s+/g, " ");
44
+ if (cleaned.length <= maxLength) return cleaned;
45
+ return cleaned.slice(0, maxLength - 3) + "...";
46
+ }
47
+ function getTaskDisplayContent(transcript, config) {
48
+ const nestedTasks = getNestedTasks(transcript);
49
+ if (nestedTasks.length === 0) {
50
+ const latestOutput = getLatestOutput(transcript);
51
+ return {
52
+ type: "simple",
53
+ content: truncate(latestOutput, config.maxCharsWithoutChildren)
54
+ };
55
+ }
56
+ const tasksToShow = config.showAllChildren ? nestedTasks : nestedTasks.slice(-config.maxRecentChildren);
57
+ const children = tasksToShow.map((task) => ({
58
+ description: task.description,
59
+ status: task.status,
60
+ content: truncate(getLatestOutput(task), config.maxCharsPerChild)
61
+ }));
62
+ return {
63
+ type: "nested",
64
+ children,
65
+ hiddenCount: nestedTasks.length - tasksToShow.length
66
+ };
67
+ }
68
+ function getStatusIcon(status) {
69
+ switch (status) {
70
+ case "pending":
71
+ return "\u25CB";
72
+ // 空心圆 - pending
73
+ case "running":
74
+ return SYMBOLS.TOOL_RUNNING;
75
+ // ◐ 半圆 - in progress
76
+ case "completed":
77
+ return "\u25CF";
78
+ // 实心圆 - completed (视觉进度: ○→◐→●)
79
+ case "failed":
80
+ return SYMBOLS.TOOL_ERROR;
81
+ // ✗ - failed
82
+ case "interrupted":
83
+ return "\u2298";
84
+ default:
85
+ return "\u25CB";
86
+ }
87
+ }
88
+ function getStatusColor(status) {
89
+ switch (status) {
90
+ case "pending":
91
+ return SEMANTIC_COLORS.dim;
92
+ case "running":
93
+ return SEMANTIC_COLORS.running;
94
+ case "completed":
95
+ return SEMANTIC_COLORS.success;
96
+ case "failed":
97
+ return SEMANTIC_COLORS.error;
98
+ case "interrupted":
99
+ return SEMANTIC_COLORS.dim;
100
+ default:
101
+ return SEMANTIC_COLORS.dim;
102
+ }
103
+ }
104
+ function formatDuration(durationMs) {
105
+ if (durationMs === void 0 || durationMs === null) {
106
+ return "--";
107
+ }
108
+ const seconds = durationMs / 1e3;
109
+ if (seconds < 60) {
110
+ return `${seconds.toFixed(1)}s`;
111
+ }
112
+ const minutes = Math.floor(seconds / 60);
113
+ const remainingSeconds = Math.floor(seconds % 60);
114
+ return `${minutes}m ${remainingSeconds}s`;
115
+ }
116
+ function formatModelName(model) {
117
+ if (!model) return "";
118
+ if (model.includes("opus")) return "opus";
119
+ if (model.includes("sonnet")) return "sonnet";
120
+ if (model.includes("haiku")) return "haiku";
121
+ const parts = model.split("-");
122
+ if (parts.length > 2 && model.length > 15) {
123
+ return parts.slice(0, 2).join("-");
124
+ }
125
+ return model;
126
+ }
127
+ function formatTimestamp(timestamp) {
128
+ if (!timestamp) return "";
129
+ const date = timestamp instanceof Date ? timestamp : new Date(timestamp);
130
+ const hours = date.getHours();
131
+ const minutes = date.getMinutes().toString().padStart(2, "0");
132
+ return `${hours}:${minutes}`;
133
+ }
134
+ function formatMetaInfo(meta) {
135
+ const parts = [];
136
+ if (meta.duration !== void 0 && meta.duration !== null) {
137
+ parts.push(formatDuration(meta.duration));
138
+ }
139
+ const modelName = formatModelName(meta.model);
140
+ if (modelName) {
141
+ parts.push(modelName);
142
+ }
143
+ const time = formatTimestamp(meta.timestamp);
144
+ if (time) {
145
+ parts.push(time);
146
+ }
147
+ return parts.join(" \xB7 ");
148
+ }
149
+ function getToolUseHistory(transcript) {
150
+ const history = [];
151
+ const completedToolIds = /* @__PURE__ */ new Set();
152
+ for (const msg of transcript.messages) {
153
+ if (msg.type === "user") {
154
+ const content = msg.message.content;
155
+ if (!Array.isArray(content)) continue;
156
+ for (const block of content) {
157
+ if (block.type === "tool_result" && "tool_use_id" in block) {
158
+ completedToolIds.add(block.tool_use_id);
159
+ }
160
+ }
161
+ }
162
+ }
163
+ for (let i = 0; i < transcript.messages.length; i++) {
164
+ const msg = transcript.messages[i];
165
+ if (msg.type === "assistant") {
166
+ const content = msg.message.content;
167
+ if (!content || !Array.isArray(content)) continue;
168
+ for (const block of content) {
169
+ if (block.type === "tool_use") {
170
+ const toolUse = block;
171
+ const description = getToolUseDescription(toolUse);
172
+ const isExecuting = !completedToolIds.has(toolUse.id);
173
+ history.push({
174
+ name: toolUse.name,
175
+ id: toolUse.id,
176
+ description,
177
+ messageIndex: i,
178
+ isExecuting
179
+ });
180
+ }
181
+ }
182
+ }
183
+ }
184
+ return history;
185
+ }
186
+ function getFileName(filePath) {
187
+ const parts = filePath.split("/");
188
+ return parts[parts.length - 1] || filePath;
189
+ }
190
+ const TOOL_DISPLAY_NAMES = {
191
+ View: "Read"
192
+ // Add more mappings as needed
193
+ };
194
+ function getToolDisplayName(internalName) {
195
+ return TOOL_DISPLAY_NAMES[internalName] || internalName;
196
+ }
197
+ function getToolUseDescription(toolUse) {
198
+ const input = toolUse.input;
199
+ switch (toolUse.name) {
200
+ case "Read":
201
+ case "View":
202
+ return input.file_path ? getFileName(String(input.file_path)) : "file";
203
+ case "Write":
204
+ return input.file_path ? getFileName(String(input.file_path)) : "file";
205
+ case "Edit":
206
+ return input.file_path ? getFileName(String(input.file_path)) : "file";
207
+ case "Glob":
208
+ return input.pattern ? String(input.pattern) : "files";
209
+ case "Grep":
210
+ return input.pattern ? `"${input.pattern}"` : "content";
211
+ case "Bash":
212
+ return input.command ? String(input.command).slice(0, 50) + (String(input.command).length > 50 ? "..." : "") : "command";
213
+ case "Task":
214
+ return input.description ? String(input.description) : "sub-task";
215
+ case "WebFetch":
216
+ return input.url ? String(input.url) : "URL";
217
+ case "WebSearch":
218
+ return input.query ? String(input.query) : "web";
219
+ default:
220
+ if (input.file_path) return getFileName(String(input.file_path));
221
+ if (input.path) return getFileName(String(input.path));
222
+ if (input.query) return String(input.query);
223
+ if (input.pattern) return String(input.pattern);
224
+ return "";
225
+ }
226
+ }
227
+ function getToolUseHistoryForDisplay(transcript, config) {
228
+ const allTools = getToolUseHistory(transcript);
229
+ if (config.showAllChildren) {
230
+ return { tools: allTools, hiddenCount: 0 };
231
+ }
232
+ const maxTools = config.maxRecentChildren;
233
+ if (allTools.length <= maxTools) {
234
+ return { tools: allTools, hiddenCount: 0 };
235
+ }
236
+ const recentTools = allTools.slice(-maxTools);
237
+ return {
238
+ tools: recentTools,
239
+ hiddenCount: allTools.length - maxTools
240
+ };
241
+ }
242
+ export {
243
+ formatDuration,
244
+ formatMetaInfo,
245
+ formatModelName,
246
+ formatTimestamp,
247
+ getLatestOutput,
248
+ getNestedTasks,
249
+ getStatusColor,
250
+ getStatusIcon,
251
+ getTaskDisplayContent,
252
+ getToolDisplayName,
253
+ getToolUseHistory,
254
+ getToolUseHistoryForDisplay,
255
+ truncate
256
+ };
257
+ //# sourceMappingURL=taskDisplayUtils.js.map