@within-7/minto 0.3.9 → 0.4.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 (383) hide show
  1. package/dist/Tool.js.map +2 -2
  2. package/dist/commands/agents/AgentsCommand.js +461 -657
  3. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  4. package/dist/commands/agents/types.js +1 -0
  5. package/dist/commands/agents/types.js.map +2 -2
  6. package/dist/commands/agents/utils/fileOperations.js +96 -36
  7. package/dist/commands/agents/utils/fileOperations.js.map +3 -3
  8. package/dist/commands/agents/utils/index.js +3 -1
  9. package/dist/commands/agents/utils/index.js.map +2 -2
  10. package/dist/commands/context.js +54 -23
  11. package/dist/commands/context.js.map +2 -2
  12. package/dist/commands/ctx_viz.js +1 -1
  13. package/dist/commands/effort.js +87 -0
  14. package/dist/commands/effort.js.map +7 -0
  15. package/dist/commands/export.js +684 -94
  16. package/dist/commands/export.js.map +2 -2
  17. package/dist/commands/ide.js +18 -0
  18. package/dist/commands/ide.js.map +7 -0
  19. package/dist/commands/language.js +19 -46
  20. package/dist/commands/language.js.map +2 -2
  21. package/dist/commands/mcp-interactive.js +425 -217
  22. package/dist/commands/mcp-interactive.js.map +2 -2
  23. package/dist/commands/memory.js +168 -0
  24. package/dist/commands/memory.js.map +7 -0
  25. package/dist/commands/model.js +457 -65
  26. package/dist/commands/model.js.map +2 -2
  27. package/dist/commands/outputStyle.js +64 -0
  28. package/dist/commands/outputStyle.js.map +7 -0
  29. package/dist/commands/permissions.js +75 -49
  30. package/dist/commands/permissions.js.map +2 -2
  31. package/dist/commands/plugin/utils.js +33 -1
  32. package/dist/commands/plugin/utils.js.map +2 -2
  33. package/dist/commands/plugin.js +891 -185
  34. package/dist/commands/plugin.js.map +3 -3
  35. package/dist/commands/refreshCommands.js +2 -0
  36. package/dist/commands/refreshCommands.js.map +2 -2
  37. package/dist/commands/resume.js +1 -1
  38. package/dist/commands/resume.js.map +1 -1
  39. package/dist/commands/review.js +51 -0
  40. package/dist/commands/review.js.map +7 -0
  41. package/dist/commands/sandbox.js +168 -70
  42. package/dist/commands/sandbox.js.map +2 -2
  43. package/dist/commands/setup.js +593 -107
  44. package/dist/commands/setup.js.map +2 -2
  45. package/dist/commands/stats.js +188 -131
  46. package/dist/commands/stats.js.map +2 -2
  47. package/dist/commands/status.js +75 -13
  48. package/dist/commands/status.js.map +2 -2
  49. package/dist/commands/terminalSetup.js +6 -0
  50. package/dist/commands/terminalSetup.js.map +2 -2
  51. package/dist/commands/undo.js +146 -174
  52. package/dist/commands/undo.js.map +2 -2
  53. package/dist/commands/vim.js +22 -0
  54. package/dist/commands/vim.js.map +7 -0
  55. package/dist/commands.js +12 -0
  56. package/dist/commands.js.map +2 -2
  57. package/dist/components/Help.js +165 -32
  58. package/dist/components/Help.js.map +2 -2
  59. package/dist/components/HighlightedCode.js +1 -0
  60. package/dist/components/HighlightedCode.js.map +2 -2
  61. package/dist/components/InfoPanel/InfoPanel.js +123 -0
  62. package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
  63. package/dist/components/InfoPanel/index.js +5 -0
  64. package/dist/components/InfoPanel/index.js.map +7 -0
  65. package/dist/components/InfoPanel/types.js +1 -0
  66. package/dist/components/InfoPanel/types.js.map +7 -0
  67. package/dist/components/ModelSelector/BrandTextInput.js +43 -0
  68. package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
  69. package/dist/components/ModelSelector/ModelSelector.js +590 -565
  70. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  71. package/dist/components/ModelSelector/WizardContainer.js +45 -0
  72. package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
  73. package/dist/components/ModelSelector/index.js +1 -3
  74. package/dist/components/ModelSelector/index.js.map +2 -2
  75. package/dist/components/PromptInput.js +26 -11
  76. package/dist/components/PromptInput.js.map +2 -2
  77. package/dist/components/PulseLabel.js +44 -0
  78. package/dist/components/PulseLabel.js.map +7 -0
  79. package/dist/components/RequestStatusIndicator.js +1 -1
  80. package/dist/components/RequestStatusIndicator.js.map +1 -1
  81. package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
  82. package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
  83. package/dist/components/SimpleSelector/index.js +5 -0
  84. package/dist/components/SimpleSelector/index.js.map +7 -0
  85. package/dist/components/SimpleSelector/types.js +1 -0
  86. package/dist/components/SimpleSelector/types.js.map +7 -0
  87. package/dist/components/Spinner.js +12 -42
  88. package/dist/components/Spinner.js.map +3 -3
  89. package/dist/components/StartupStatus.js +57 -0
  90. package/dist/components/StartupStatus.js.map +7 -0
  91. package/dist/components/StatusOverlayContent.js +21 -0
  92. package/dist/components/StatusOverlayContent.js.map +7 -0
  93. package/dist/components/SubagentBlock.js +43 -6
  94. package/dist/components/SubagentBlock.js.map +2 -2
  95. package/dist/components/TabbedListView/ScrollableList.js +31 -5
  96. package/dist/components/TabbedListView/ScrollableList.js.map +2 -2
  97. package/dist/components/TabbedListView/TabBar.js +13 -8
  98. package/dist/components/TabbedListView/TabBar.js.map +2 -2
  99. package/dist/components/TabbedListView/TabbedListView.js +123 -48
  100. package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
  101. package/dist/components/TodoPanel.js +1 -1
  102. package/dist/components/TodoPanel.js.map +1 -1
  103. package/dist/components/ToolUseLoader.js +5 -0
  104. package/dist/components/ToolUseLoader.js.map +2 -2
  105. package/dist/components/TrustDialog.js +0 -2
  106. package/dist/components/TrustDialog.js.map +2 -2
  107. package/dist/components/messages/TaskInModuleView.js +1 -1
  108. package/dist/components/messages/TaskInModuleView.js.map +2 -2
  109. package/dist/components/messages/TaskToolMessage.js +1 -1
  110. package/dist/components/messages/TaskToolMessage.js.map +2 -2
  111. package/dist/components/messages/UserPromptMessage.js +6 -1
  112. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  113. package/dist/constants/modelCapabilities.js +103 -18
  114. package/dist/constants/modelCapabilities.js.map +2 -2
  115. package/dist/constants/product.js +2 -0
  116. package/dist/constants/product.js.map +2 -2
  117. package/dist/constants/prompts/agentPrompt.js +30 -0
  118. package/dist/constants/prompts/agentPrompt.js.map +7 -0
  119. package/dist/constants/prompts/codeConventions.js +27 -0
  120. package/dist/constants/prompts/codeConventions.js.map +7 -0
  121. package/dist/constants/prompts/doingTasks.js +15 -0
  122. package/dist/constants/prompts/doingTasks.js.map +7 -0
  123. package/dist/constants/prompts/envInfo.js +17 -0
  124. package/dist/constants/prompts/envInfo.js.map +7 -0
  125. package/dist/constants/prompts/executingWithCare.js +17 -0
  126. package/dist/constants/prompts/executingWithCare.js.map +7 -0
  127. package/dist/constants/prompts/identity.js +10 -0
  128. package/dist/constants/prompts/identity.js.map +7 -0
  129. package/dist/constants/prompts/index.js +78 -0
  130. package/dist/constants/prompts/index.js.map +7 -0
  131. package/dist/constants/prompts/taskManagement.js +60 -0
  132. package/dist/constants/prompts/taskManagement.js.map +7 -0
  133. package/dist/constants/prompts/toneAndStyle.js +62 -0
  134. package/dist/constants/prompts/toneAndStyle.js.map +7 -0
  135. package/dist/constants/prompts/toolUsagePolicy.js +38 -0
  136. package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
  137. package/dist/constants/prompts.js +5 -176
  138. package/dist/constants/prompts.js.map +2 -2
  139. package/dist/constants/providerRegistry.js +235 -0
  140. package/dist/constants/providerRegistry.js.map +7 -0
  141. package/dist/constants/providers.js +35 -0
  142. package/dist/constants/providers.js.map +7 -0
  143. package/dist/context/PermissionContext.js +0 -1
  144. package/dist/context/PermissionContext.js.map +2 -2
  145. package/dist/context.js +87 -31
  146. package/dist/context.js.map +2 -2
  147. package/dist/core/backupHook.js +29 -0
  148. package/dist/core/backupHook.js.map +7 -0
  149. package/dist/core/config/defaults.js +11 -2
  150. package/dist/core/config/defaults.js.map +2 -2
  151. package/dist/core/config/schema.js +21 -3
  152. package/dist/core/config/schema.js.map +2 -2
  153. package/dist/core/costTracker.js +18 -16
  154. package/dist/core/costTracker.js.map +2 -2
  155. package/dist/core/index.js +0 -1
  156. package/dist/core/index.js.map +2 -2
  157. package/dist/core/tokenStatsManager.js +22 -4
  158. package/dist/core/tokenStatsManager.js.map +2 -2
  159. package/dist/cost-tracker.js +0 -16
  160. package/dist/cost-tracker.js.map +2 -2
  161. package/dist/entrypoints/bootstrap.js +3 -1
  162. package/dist/entrypoints/bootstrap.js.map +2 -2
  163. package/dist/entrypoints/cli.js +81 -68
  164. package/dist/entrypoints/cli.js.map +2 -2
  165. package/dist/hooks/useAgentTokenStats.js +1 -1
  166. package/dist/hooks/useAgentTokenStats.js.map +2 -2
  167. package/dist/hooks/useAgentTranscripts.js +2 -1
  168. package/dist/hooks/useAgentTranscripts.js.map +2 -2
  169. package/dist/hooks/useBackgroundShells.js +29 -0
  170. package/dist/hooks/useBackgroundShells.js.map +7 -0
  171. package/dist/hooks/useCanUseTool.js +1 -1
  172. package/dist/hooks/useCanUseTool.js.map +2 -2
  173. package/dist/hooks/useDeferredLoading.js +64 -0
  174. package/dist/hooks/useDeferredLoading.js.map +7 -0
  175. package/dist/hooks/useHookStatus.js +1 -1
  176. package/dist/hooks/useHookStatus.js.map +2 -2
  177. package/dist/hooks/useSessionTracking.js +55 -0
  178. package/dist/hooks/useSessionTracking.js.map +7 -0
  179. package/dist/hooks/useTerminalSize.js +21 -0
  180. package/dist/hooks/useTerminalSize.js.map +2 -2
  181. package/dist/hooks/useTextInput.js +1 -0
  182. package/dist/hooks/useTextInput.js.map +2 -2
  183. package/dist/hooks/useUnifiedCompletion.js +3 -2
  184. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  185. package/dist/i18n/locales/en.js +299 -1
  186. package/dist/i18n/locales/en.js.map +2 -2
  187. package/dist/i18n/locales/zh-CN.js +300 -2
  188. package/dist/i18n/locales/zh-CN.js.map +2 -2
  189. package/dist/i18n/types.js.map +1 -1
  190. package/dist/messages.js +41 -17
  191. package/dist/messages.js.map +2 -2
  192. package/dist/permissions.js +94 -1
  193. package/dist/permissions.js.map +2 -2
  194. package/dist/query.js +27 -19
  195. package/dist/query.js.map +2 -2
  196. package/dist/screens/REPL.js +83 -74
  197. package/dist/screens/REPL.js.map +2 -2
  198. package/dist/services/adapters/responsesAPI.js +6 -0
  199. package/dist/services/adapters/responsesAPI.js.map +2 -2
  200. package/dist/services/agentTeams/index.js +35 -0
  201. package/dist/services/agentTeams/index.js.map +7 -0
  202. package/dist/services/agentTeams/mailbox.js +114 -0
  203. package/dist/services/agentTeams/mailbox.js.map +7 -0
  204. package/dist/services/agentTeams/teamManager.js +149 -0
  205. package/dist/services/agentTeams/teamManager.js.map +7 -0
  206. package/dist/services/agentTeams/teamTaskStore.js +114 -0
  207. package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
  208. package/dist/services/agentTeams/teammateSpawner.js +80 -0
  209. package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
  210. package/dist/services/checkpointManager.js +16 -3
  211. package/dist/services/checkpointManager.js.map +2 -2
  212. package/dist/services/claude.js +19 -1728
  213. package/dist/services/claude.js.map +3 -3
  214. package/dist/services/customCommands.js +30 -8
  215. package/dist/services/customCommands.js.map +2 -2
  216. package/dist/services/gpt5ConnectionTest.js +4 -2
  217. package/dist/services/gpt5ConnectionTest.js.map +2 -2
  218. package/dist/services/hookExecutor.js +411 -127
  219. package/dist/services/hookExecutor.js.map +2 -2
  220. package/dist/services/llm/anthropicProvider.js +807 -0
  221. package/dist/services/llm/anthropicProvider.js.map +7 -0
  222. package/dist/services/llm/dispatch.js +218 -0
  223. package/dist/services/llm/dispatch.js.map +7 -0
  224. package/dist/services/llm/index.js +44 -0
  225. package/dist/services/llm/index.js.map +7 -0
  226. package/dist/services/llm/mintoContext.js +69 -0
  227. package/dist/services/llm/mintoContext.js.map +7 -0
  228. package/dist/services/llm/openaiProvider.js +622 -0
  229. package/dist/services/llm/openaiProvider.js.map +7 -0
  230. package/dist/services/llm/types.js +157 -0
  231. package/dist/services/llm/types.js.map +7 -0
  232. package/dist/services/mcpClient.js +183 -33
  233. package/dist/services/mcpClient.js.map +2 -2
  234. package/dist/services/notifier.js +14 -0
  235. package/dist/services/notifier.js.map +2 -2
  236. package/dist/services/oauth.js +4 -2
  237. package/dist/services/oauth.js.map +2 -2
  238. package/dist/services/openai.js +66 -56
  239. package/dist/services/openai.js.map +3 -3
  240. package/dist/services/outputStyles.js +102 -21
  241. package/dist/services/outputStyles.js.map +2 -2
  242. package/dist/services/plugins/lspServers.js +1 -1
  243. package/dist/services/plugins/lspServers.js.map +2 -2
  244. package/dist/services/plugins/pluginRuntime.js +2 -1
  245. package/dist/services/plugins/pluginRuntime.js.map +2 -2
  246. package/dist/services/plugins/pluginValidation.js +10 -3
  247. package/dist/services/plugins/pluginValidation.js.map +2 -2
  248. package/dist/services/plugins/skillMarketplace.js +20 -9
  249. package/dist/services/plugins/skillMarketplace.js.map +2 -2
  250. package/dist/services/sentry.js +1 -1
  251. package/dist/services/sentry.js.map +2 -2
  252. package/dist/services/sessionMemory.js +16 -3
  253. package/dist/services/sessionMemory.js.map +2 -2
  254. package/dist/services/systemReminder.js +367 -9
  255. package/dist/services/systemReminder.js.map +2 -2
  256. package/dist/services/taskStore.js +19 -0
  257. package/dist/services/taskStore.js.map +2 -2
  258. package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
  259. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
  260. package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
  261. package/dist/tools/BashTool/BashTool.js +28 -0
  262. package/dist/tools/BashTool/BashTool.js.map +2 -2
  263. package/dist/tools/FileEditTool/FileEditTool.js +8 -1
  264. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  265. package/dist/tools/FileReadTool/FileReadTool.js +14 -0
  266. package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
  267. package/dist/tools/FileWriteTool/FileWriteTool.js +10 -1
  268. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  269. package/dist/tools/GlobTool/GlobTool.js.map +1 -1
  270. package/dist/tools/GrepTool/GrepTool.js.map +1 -1
  271. package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
  272. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
  273. package/dist/tools/LspTool/LspTool.js +11 -2
  274. package/dist/tools/LspTool/LspTool.js.map +2 -2
  275. package/dist/tools/MCPTool/MCPTool.js.map +1 -1
  276. package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
  277. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  278. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
  279. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  280. package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
  281. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  282. package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
  283. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  284. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
  285. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
  286. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
  287. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
  288. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
  289. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
  290. package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
  291. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
  292. package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
  293. package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
  294. package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
  295. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
  296. package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
  297. package/dist/tools/TaskTool/TaskTool.js +84 -11
  298. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  299. package/dist/tools/TaskTool/prompt.js +12 -6
  300. package/dist/tools/TaskTool/prompt.js.map +2 -2
  301. package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
  302. package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
  303. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
  304. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
  305. package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
  306. package/dist/tools/WebSearchTool/searchProviders.js +2 -1
  307. package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
  308. package/dist/tools/lsTool/lsTool.js.map +2 -2
  309. package/dist/tools/lsTool/prompt.js.map +1 -1
  310. package/dist/tools.js +14 -3
  311. package/dist/tools.js.map +2 -2
  312. package/dist/types/PermissionMode.js +21 -1
  313. package/dist/types/PermissionMode.js.map +2 -2
  314. package/dist/types/agentTeams.js +1 -0
  315. package/dist/types/agentTeams.js.map +7 -0
  316. package/dist/types/hooks.js +8 -2
  317. package/dist/types/hooks.js.map +2 -2
  318. package/dist/types/plugin.js +3 -5
  319. package/dist/types/plugin.js.map +2 -2
  320. package/dist/utils/agentHookExecutor.js +1 -4
  321. package/dist/utils/agentHookExecutor.js.map +2 -2
  322. package/dist/utils/agentLoader.js +91 -15
  323. package/dist/utils/agentLoader.js.map +2 -2
  324. package/dist/utils/agentMemory.js.map +2 -2
  325. package/dist/utils/animationManager.js +1 -1
  326. package/dist/utils/animationManager.js.map +2 -2
  327. package/dist/utils/ask.js +1 -1
  328. package/dist/utils/async.js +5 -1
  329. package/dist/utils/async.js.map +2 -2
  330. package/dist/utils/autoCompactCore.js +60 -0
  331. package/dist/utils/autoCompactCore.js.map +2 -2
  332. package/dist/utils/claudeCodeSync.js +439 -0
  333. package/dist/utils/claudeCodeSync.js.map +7 -0
  334. package/dist/utils/config.js +27 -151
  335. package/dist/utils/config.js.map +2 -2
  336. package/dist/utils/configSchema.js +227 -0
  337. package/dist/utils/configSchema.js.map +7 -0
  338. package/dist/utils/debugLogger.js.map +2 -2
  339. package/dist/utils/env.js +4 -3
  340. package/dist/utils/env.js.map +2 -2
  341. package/dist/utils/envConfig.js +34 -0
  342. package/dist/utils/envConfig.js.map +3 -3
  343. package/dist/utils/execFileNoThrow.js +2 -1
  344. package/dist/utils/execFileNoThrow.js.map +2 -2
  345. package/dist/utils/gpt5.js +146 -0
  346. package/dist/utils/gpt5.js.map +7 -0
  347. package/dist/utils/hookManager.js +374 -140
  348. package/dist/utils/hookManager.js.map +2 -2
  349. package/dist/utils/markdown.js +47 -0
  350. package/dist/utils/markdown.js.map +2 -2
  351. package/dist/utils/marketplaceManager.js +80 -43
  352. package/dist/utils/marketplaceManager.js.map +2 -2
  353. package/dist/utils/memoizeWithTTL.js +25 -0
  354. package/dist/utils/memoizeWithTTL.js.map +7 -0
  355. package/dist/utils/messages.js +2 -2
  356. package/dist/utils/messages.js.map +2 -2
  357. package/dist/utils/model.js +34 -9
  358. package/dist/utils/model.js.map +2 -2
  359. package/dist/utils/pluginInstaller.js +68 -29
  360. package/dist/utils/pluginInstaller.js.map +2 -2
  361. package/dist/utils/pluginLoader.js +249 -57
  362. package/dist/utils/pluginLoader.js.map +2 -2
  363. package/dist/utils/repoFetcher.js +110 -0
  364. package/dist/utils/repoFetcher.js.map +7 -0
  365. package/dist/utils/safeFetch.js +45 -0
  366. package/dist/utils/safeFetch.js.map +7 -0
  367. package/dist/utils/skillLoader.js +77 -12
  368. package/dist/utils/skillLoader.js.map +2 -2
  369. package/dist/utils/streamingState.js +52 -0
  370. package/dist/utils/streamingState.js.map +7 -0
  371. package/dist/utils/stringSubstitution.js +4 -5
  372. package/dist/utils/stringSubstitution.js.map +2 -2
  373. package/dist/utils/style.js +6 -3
  374. package/dist/utils/style.js.map +2 -2
  375. package/dist/utils/teamConfig.js +162 -16
  376. package/dist/utils/teamConfig.js.map +2 -2
  377. package/dist/utils/terminal.js +1 -1
  378. package/dist/utils/terminal.js.map +2 -2
  379. package/dist/utils/toolRiskClassification.js +0 -6
  380. package/dist/utils/toolRiskClassification.js.map +2 -2
  381. package/dist/version.js +2 -2
  382. package/dist/version.js.map +1 -1
  383. package/package.json +7 -6
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/mcp-interactive.tsx"],
4
- "sourcesContent": ["/**\n * Interactive MCP Server Management UI\n *\n * Complete interactive interface for MCP server management with navigation\n */\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { Select } from '@components/CustomSelect/select'\nimport { getTheme } from '@utils/theme'\nimport { SEMANTIC_COLORS } from '@constants/colors'\nimport { Command } from '@commands'\nimport {\n listMCPServers,\n getClients,\n refreshMCPConnections,\n getMcpServer,\n addMcpServer,\n removeMcpServer,\n type ScopedMcpServerConfig,\n} from '@services/mcpClient'\nimport { SimpleSpinner } from '@components/Spinner'\nimport {\n getCurrentProjectConfig,\n saveCurrentProjectConfig,\n} from '@utils/config'\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype Screen = 'main-menu' | 'server-list' | 'server-details'\n\ntype NavigationState = {\n screen: Screen\n serverName?: string\n}\n\ntype ServerStatus = {\n name: string\n status: 'connected' | 'failed'\n config: ScopedMcpServerConfig\n}\n\n// =============================================================================\n// Main Menu\n// =============================================================================\n\nconst MainMenu: React.FC<{\n onNavigate: (state: NavigationState) => void\n onExit: () => void\n isActive?: boolean\n}> = ({ onNavigate, onExit, isActive = true }) => {\n const theme = getTheme()\n\n const options = [\n { label: '\uD83D\uDCCB View all MCP servers', value: 'list' },\n { label: '\uD83D\uDD04 Refresh connections', value: 'refresh' },\n ]\n\n // Only listen when this component is active\n useInput(\n (input, key) => {\n if (key.escape) onExit()\n },\n { isActive },\n )\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.primary}\n padding={1}\n >\n <Box marginBottom={1}>\n <Text bold color={theme.primary}>\n MCP Server Manager\n </Text>\n </Box>\n\n <Select\n options={options}\n onChange={value => {\n if (value === 'list') onNavigate({ screen: 'server-list' })\n else if (value === 'refresh') {\n refreshMCPConnections()\n onNavigate({ screen: 'server-list' })\n }\n }}\n />\n\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>\n Press <Text bold>ESC</Text> to exit\n </Text>\n </Box>\n </Box>\n )\n}\n\n// =============================================================================\n// Server List\n// =============================================================================\n\nconst ServerList: React.FC<{\n onNavigate: (state: NavigationState) => void\n onBack: () => void\n isActive?: boolean\n}> = ({ onNavigate, onBack, isActive = true }) => {\n const theme = getTheme()\n const [loading, setLoading] = useState(true)\n const [servers, setServers] = useState<ServerStatus[]>([])\n\n useEffect(() => {\n const loadServers = async () => {\n const serverConfigs = listMCPServers()\n const clients = await getClients()\n\n const serverStatuses: ServerStatus[] = Object.entries(serverConfigs).map(\n ([name, _]) => {\n const client = clients.find(c => c.name === name)\n const config = getMcpServer(name)!\n return {\n name,\n status: client?.type === 'connected' ? 'connected' : 'failed',\n config,\n }\n },\n )\n\n setServers(serverStatuses)\n setLoading(false)\n }\n\n loadServers()\n }, [])\n\n // Memoize the onChange handler to prevent infinite re-renders\n const handleServerSelect = useCallback(\n (serverName: string) => {\n onNavigate({ screen: 'server-details', serverName })\n },\n [onNavigate],\n )\n\n // Only listen when this component is active\n useInput(\n (input, key) => {\n if (key.escape) onBack()\n },\n { isActive },\n )\n\n if (loading) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <SimpleSpinner label=\"Loading MCP servers...\" />\n </Box>\n )\n }\n\n if (servers.length === 0) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text>No MCP servers configured.</Text>\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>\n Press <Text bold>ESC</Text> to go back\n </Text>\n </Box>\n </Box>\n )\n }\n\n const options = servers.map(server => {\n const statusIcon = server.status === 'connected' ? '\u2713' : '\u2717'\n const statusColor =\n server.status === 'connected' ? theme.success : theme.error\n return {\n label: (\n <Text>\n <Text color={statusColor}>{statusIcon}</Text> {server.name}{' '}\n <Text color={SEMANTIC_COLORS.dim}>({server.config.scope})</Text>\n </Text>\n ),\n value: server.name,\n }\n })\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.primary}\n padding={1}\n >\n <Box marginBottom={1}>\n <Text bold color={theme.primary}>\n MCP Servers\n </Text>\n </Box>\n\n <Select options={options} onChange={handleServerSelect} />\n\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>\n Press <Text bold>ESC</Text> to go back\n </Text>\n </Box>\n </Box>\n )\n}\n\n// =============================================================================\n// Server Details\n// =============================================================================\n\nconst ServerDetails: React.FC<{\n serverName: string\n onBack: () => void\n onRefresh: () => void\n isActive?: boolean\n}> = ({ serverName, onBack, onRefresh, isActive = true }) => {\n const theme = getTheme()\n const [loading, setLoading] = useState(true)\n const [server, setServer] = useState<ServerStatus | null>(null)\n const [toggling, setToggling] = useState(false)\n\n useEffect(() => {\n const loadServer = async () => {\n const config = getMcpServer(serverName)\n if (!config) {\n onBack()\n return\n }\n\n const clients = await getClients()\n const client = clients.find(c => c.name === serverName)\n\n setServer({\n name: serverName,\n status: client?.type === 'connected' ? 'connected' : 'failed',\n config,\n })\n setLoading(false)\n }\n\n loadServer()\n }, [serverName])\n\n const toggleEnabled = async () => {\n if (!server) return\n\n setToggling(true)\n\n // Get current project config\n const projectConfig = getCurrentProjectConfig()\n const currentServer = projectConfig.mcpServers?.[serverName]\n\n if (currentServer) {\n // Toggle in project config\n const newEnabled = !(currentServer.enabled ?? true)\n await saveCurrentProjectConfig({\n ...projectConfig,\n mcpServers: {\n ...projectConfig.mcpServers,\n [serverName]: {\n ...currentServer,\n enabled: newEnabled,\n },\n },\n })\n } else {\n // Server is from global or mcprc, copy to project and disable\n const serverConfig = getMcpServer(serverName)\n if (serverConfig) {\n await saveCurrentProjectConfig({\n ...projectConfig,\n mcpServers: {\n ...projectConfig.mcpServers,\n [serverName]: {\n ...serverConfig,\n enabled: false,\n },\n },\n })\n }\n }\n\n setToggling(false)\n refreshMCPConnections()\n onRefresh()\n }\n\n // Only listen when this component is active\n useInput(\n (input, key) => {\n if (key.escape) onBack()\n },\n { isActive },\n )\n\n if (loading) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <SimpleSpinner label=\"Loading server details...\" />\n </Box>\n )\n }\n\n if (!server) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text color={theme.error}>Server not found</Text>\n </Box>\n )\n }\n\n const isEnabled = 'enabled' in server.config ? server.config.enabled : true\n const statusColor =\n server.status === 'connected' ? theme.success : theme.error\n const enabledColor = isEnabled ? theme.success : theme.error\n\n const options = [\n {\n label: isEnabled ? '\uD83D\uDD34 Disable server' : '\uD83D\uDFE2 Enable server',\n value: 'toggle',\n },\n { label: '\uD83D\uDD04 Refresh connection', value: 'refresh' },\n { label: '\u2190 Back to list', value: 'back' },\n ]\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.primary}\n padding={1}\n >\n <Box marginBottom={1}>\n <Text bold color={theme.primary}>\n {server.name}\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text>\n Status: <Text color={statusColor}>{server.status}</Text>\n </Text>\n <Text>\n Enabled: <Text color={enabledColor}>{isEnabled ? 'Yes' : 'No'}</Text>\n </Text>\n <Text>\n Scope: <Text color={SEMANTIC_COLORS.dim}>{server.config.scope}</Text>\n </Text>\n <Text>\n Type: <Text color={SEMANTIC_COLORS.dim}>{server.config.type}</Text>\n </Text>\n </Box>\n\n {toggling ? (\n <SimpleSpinner label=\"Toggling server...\" />\n ) : (\n <Select\n options={options}\n onChange={value => {\n if (value === 'toggle') toggleEnabled()\n else if (value === 'refresh') {\n refreshMCPConnections()\n onRefresh()\n } else if (value === 'back') onBack()\n }}\n />\n )}\n\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>\n Press <Text bold>ESC</Text> to go back\n </Text>\n </Box>\n </Box>\n )\n}\n\n// =============================================================================\n// Main Interactive Component\n// =============================================================================\n\nconst MCPInteractive: React.FC<{\n onDone: (result?: string) => void\n}> = ({ onDone }) => {\n const [navState, setNavState] = useState<NavigationState>({\n screen: 'main-menu',\n })\n\n const handleNavigate = (state: NavigationState) => {\n setNavState(state)\n }\n\n const handleBack = () => {\n if (navState.screen === 'server-details') {\n setNavState({ screen: 'server-list' })\n } else {\n setNavState({ screen: 'main-menu' })\n }\n }\n\n const handleRefresh = () => {\n // Reload current screen\n setNavState({ ...navState })\n }\n\n switch (navState.screen) {\n case 'main-menu':\n return <MainMenu onNavigate={handleNavigate} onExit={() => onDone()} />\n\n case 'server-list':\n return <ServerList onNavigate={handleNavigate} onBack={handleBack} />\n\n case 'server-details':\n return (\n <ServerDetails\n serverName={navState.serverName!}\n onBack={handleBack}\n onRefresh={handleRefresh}\n />\n )\n\n default:\n return <Text>Unknown screen</Text>\n }\n}\n\n// =============================================================================\n// Command Definition\n// =============================================================================\n\nconst mcpInteractive = {\n type: 'local-jsx',\n name: 'mcp',\n description: 'Interactive MCP server management',\n isEnabled: true,\n isHidden: false,\n async call(onDone: (result?: string) => void) {\n return <MCPInteractive onDone={onDone} />\n },\n userFacingName() {\n return 'mcp'\n },\n} satisfies Command\n\nexport default mcpInteractive\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Interactive MCP Server Management UI\n *\n * Uses TabbedListView for consistent UI matching /agents and /plugins.\n *\n * Phase flow:\n * main \u2192 (select server) \u2192 server-actions \u2192 (toggle|delete|back)\n * \u2193\n * confirm-delete \u2192 main\n * main \u2192 (Add Server) \u2192 add-name \u2192 add-command \u2192 main\n * main \u2192 (Refresh All) \u2192 main\n */\n\nimport React, { useState, useEffect, useCallback, useMemo } from 'react'\nimport { Command } from '@commands'\nimport {\n listMCPServers,\n getClients,\n refreshMCPConnections,\n getMcpServer,\n addMcpServer,\n removeMcpServer,\n type ScopedMcpServerConfig,\n} from '@services/mcpClient'\nimport {\n getCurrentProjectConfig,\n saveCurrentProjectConfig,\n} from '@utils/config'\nimport { TabbedListView } from '@components/TabbedListView/TabbedListView'\nimport type {\n ListItem,\n TabDefinition,\n StatusOverlay,\n} from '@components/TabbedListView/types'\nimport { t } from '@i18n'\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype ServerStatus = {\n name: string\n status: 'connected' | 'failed'\n config: ScopedMcpServerConfig\n}\n\ntype MCPPhase =\n | { type: 'main' }\n | { type: 'server-actions'; serverName: string; scope: string }\n | { type: 'confirm-delete'; serverName: string; scope: string }\n | { type: 'add-name' }\n | { type: 'add-command'; name: string }\n\n// Special item IDs for action entries in the list\nconst ID_ADD_SERVER = '__add__'\nconst ID_REFRESH_ALL = '__refresh__'\nconst ID_TOGGLE = '__toggle__'\nconst ID_DELETE = '__delete__'\nconst ID_BACK = '__back__'\nconst ID_CONFIRM_YES = '__yes__'\nconst ID_CONFIRM_NO = '__no__'\n\n// =============================================================================\n// Main Interactive Component\n// =============================================================================\n\nconst MCPInteractive: React.FC<{\n onDone: (result?: string) => void\n}> = ({ onDone }) => {\n const [phase, setPhase] = useState<MCPPhase>({ type: 'main' })\n const [activeTab, setActiveTab] = useState('all')\n const [searchQuery, setSearchQuery] = useState('')\n const [statusOverlay, setStatusOverlay] = useState<StatusOverlay | null>(null)\n const [servers, setServers] = useState<ServerStatus[]>([])\n const [loading, setLoading] = useState(true)\n\n // Load servers\n const loadServers = useCallback(async () => {\n try {\n const serverConfigs = listMCPServers()\n const clients = await getClients()\n\n const serverStatuses: ServerStatus[] = Object.entries(serverConfigs).map(\n ([name, _]) => {\n const client = clients.find(c => c.name === name)\n const config = getMcpServer(name)!\n return {\n name,\n status: client?.type === 'connected' ? 'connected' : 'failed',\n config,\n }\n },\n )\n\n setServers(serverStatuses)\n } catch {\n setServers([])\n }\n }, [])\n\n // Initial load\n useEffect(() => {\n setLoading(true)\n loadServers().finally(() => setLoading(false))\n }, [loadServers])\n\n // Reload on return to main\n useEffect(() => {\n if (phase.type === 'main') {\n loadServers()\n setSearchQuery('')\n }\n }, [phase, loadServers])\n\n // \u2500\u2500\u2500 Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const toggleServer = useCallback(\n async (serverName: string) => {\n setStatusOverlay({\n type: 'loading',\n message: t('commands.mcp.toggling'),\n })\n try {\n const projectConfig = getCurrentProjectConfig()\n const currentServer = projectConfig.mcpServers?.[serverName]\n\n if (currentServer) {\n const newEnabled = !(currentServer.enabled ?? true)\n await saveCurrentProjectConfig({\n ...projectConfig,\n mcpServers: {\n ...projectConfig.mcpServers,\n [serverName]: { ...currentServer, enabled: newEnabled },\n },\n })\n } else {\n const serverConfig = getMcpServer(serverName)\n if (serverConfig) {\n await saveCurrentProjectConfig({\n ...projectConfig,\n mcpServers: {\n ...projectConfig.mcpServers,\n [serverName]: { ...serverConfig, enabled: false },\n },\n })\n }\n }\n\n await refreshMCPConnections()\n await loadServers()\n setStatusOverlay({\n type: 'success',\n message: t('commands.mcp.toggleSuccess'),\n })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n setStatusOverlay({ type: 'error', message: msg })\n }\n },\n [loadServers],\n )\n\n const deleteServer = useCallback(\n async (serverName: string, scope: string) => {\n setStatusOverlay({\n type: 'loading',\n message: t('commands.mcp.deleting'),\n })\n try {\n removeMcpServer(serverName, scope as 'project' | 'global')\n await refreshMCPConnections()\n await loadServers()\n setStatusOverlay({\n type: 'success',\n message: t('commands.mcp.deleteSuccess'),\n })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n setStatusOverlay({ type: 'error', message: msg })\n }\n },\n [loadServers],\n )\n\n const addNewServer = useCallback(\n async (name: string, commandOrUrl: string) => {\n setStatusOverlay({\n type: 'loading',\n message: t('commands.mcp.adding'),\n })\n try {\n if (\n commandOrUrl.startsWith('http://') ||\n commandOrUrl.startsWith('https://')\n ) {\n addMcpServer(name, { type: 'sse', url: commandOrUrl }, 'project')\n } else {\n const parts = commandOrUrl.split(/\\s+/)\n const command = parts[0]\n const args = parts.slice(1)\n addMcpServer(\n name,\n { type: 'stdio', command, args: args.length > 0 ? args : [] },\n 'project',\n )\n }\n await refreshMCPConnections()\n await loadServers()\n setStatusOverlay({\n type: 'success',\n message: t('commands.mcp.addSuccess'),\n })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n setStatusOverlay({\n type: 'error',\n message: `${t('commands.mcp.addFailed')}: ${msg}`,\n })\n }\n },\n [loadServers],\n )\n\n const refreshAll = useCallback(async () => {\n setStatusOverlay({\n type: 'loading',\n message: t('commands.mcp.refreshing'),\n })\n try {\n await refreshMCPConnections()\n await loadServers()\n // Clear overlay directly \u2014 no success screen needed for refresh\n setStatusOverlay(null)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n setStatusOverlay({ type: 'error', message: msg })\n }\n }, [loadServers])\n\n // \u2500\u2500\u2500 Build tabs, items, title based on phase \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const { tabs, items, title, footerHint, searchEnabled, searchPlaceholder } =\n useMemo(() => {\n switch (phase.type) {\n case 'main': {\n const projectCount = servers.filter(\n s => s.config.scope === 'project',\n ).length\n const globalCount = servers.filter(\n s => s.config.scope === 'global',\n ).length\n\n const mainTabs: TabDefinition[] = [\n {\n id: 'all',\n label: t('commands.mcp.tabAll'),\n badge: servers.length,\n },\n {\n id: 'project',\n label: t('commands.mcp.tabProject'),\n badge: projectCount,\n },\n {\n id: 'global',\n label: t('commands.mcp.tabGlobal'),\n badge: globalCount,\n },\n ]\n\n // Filter servers by active tab\n const filtered =\n activeTab === 'all'\n ? servers\n : servers.filter(s => s.config.scope === activeTab)\n\n const mainItems: ListItem[] = filtered.map(server => {\n const isEnabled =\n 'enabled' in server.config ? server.config.enabled : true\n return {\n id: server.name,\n label: server.name,\n description: `${server.config.scope} \u00B7 ${server.config.type}`,\n status: !isEnabled\n ? 'disabled'\n : server.status === 'connected'\n ? 'enabled'\n : 'error',\n data: { type: 'server', server },\n }\n })\n\n // Action entries at the bottom\n mainItems.push({\n id: ID_ADD_SERVER,\n label: `+ ${t('commands.mcp.addServer')}`,\n data: { type: 'action' },\n })\n mainItems.push({\n id: ID_REFRESH_ALL,\n label: `\u21BB ${t('commands.mcp.refreshAll')}`,\n data: { type: 'action' },\n })\n\n return {\n tabs: mainTabs,\n items: mainItems,\n title: t('commands.mcp.title'),\n footerHint:\n '\u2191\u2193 Navigate \u00B7 Enter Select \u00B7 Tab Switch \u00B7 / Search \u00B7 Esc Exit',\n searchEnabled: true,\n searchPlaceholder: undefined,\n }\n }\n\n case 'server-actions': {\n const server = servers.find(s => s.name === phase.serverName)\n const isEnabled = server\n ? 'enabled' in server.config\n ? server.config.enabled\n : true\n : true\n\n const actionItems: ListItem[] = [\n {\n id: ID_TOGGLE,\n label: isEnabled\n ? t('commands.mcp.disable')\n : t('commands.mcp.enable'),\n },\n { id: ID_DELETE, label: t('commands.mcp.deleteServer') },\n { id: ID_BACK, label: `\u2190 ${t('commands.mcp.back')}` },\n ]\n\n return {\n tabs: [\n { id: 'actions', label: t('commands.mcp.actions') },\n ] as TabDefinition[],\n items: actionItems,\n title: phase.serverName,\n footerHint: '\u2191\u2193 Navigate \u00B7 Enter Select \u00B7 Esc Back',\n searchEnabled: false,\n searchPlaceholder: undefined,\n }\n }\n\n case 'confirm-delete': {\n const confirmItems: ListItem[] = [\n { id: ID_CONFIRM_YES, label: t('commands.mcp.confirmYes') },\n { id: ID_CONFIRM_NO, label: t('commands.mcp.confirmNo') },\n ]\n\n return {\n tabs: [\n { id: 'actions', label: t('commands.mcp.actions') },\n ] as TabDefinition[],\n items: confirmItems,\n title: t('commands.mcp.confirmDeleteTitle').replace(\n '{name}',\n phase.serverName,\n ),\n footerHint: '\u2191\u2193 Navigate \u00B7 Enter Select \u00B7 Esc Back',\n searchEnabled: false,\n searchPlaceholder: undefined,\n }\n }\n\n case 'add-name': {\n return {\n tabs: [\n { id: 'add', label: t('commands.mcp.addServer') },\n ] as TabDefinition[],\n items: [] as ListItem[],\n title: t('commands.mcp.addServer'),\n footerHint: t('commands.mcp.addFooterHint'),\n searchEnabled: true,\n searchPlaceholder: t('commands.mcp.addNamePlaceholder'),\n }\n }\n\n case 'add-command': {\n const exampleItems: ListItem[] = [\n {\n id: 'example-stdio',\n label: 'npx -y @modelcontextprotocol/server-xxx',\n description: 'stdio command',\n },\n {\n id: 'example-sse',\n label: 'https://example.com/mcp/sse',\n description: 'SSE endpoint',\n },\n ]\n\n return {\n tabs: [\n { id: 'add', label: t('commands.mcp.addServer') },\n ] as TabDefinition[],\n items: exampleItems,\n title: `${t('commands.mcp.addServer')}: ${phase.name}`,\n footerHint: t('commands.mcp.addCommandFooterHint'),\n searchEnabled: true,\n searchPlaceholder: t('commands.mcp.addCommandPlaceholder'),\n }\n }\n default:\n return {\n tabs: [],\n items: [],\n title: '',\n footerHint: '',\n searchEnabled: false,\n searchPlaceholder: undefined,\n }\n }\n }, [phase, activeTab, servers])\n\n // \u2500\u2500\u2500 Handle tab change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const handleTabChange = useCallback((tabId: string) => {\n setActiveTab(tabId)\n setSearchQuery('')\n }, [])\n\n // \u2500\u2500\u2500 Handle status overlay dismiss \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const handleStatusDismiss = useCallback(() => {\n setStatusOverlay(null)\n setPhase({ type: 'main' })\n }, [])\n\n // \u2500\u2500\u2500 Handle ESC / back navigation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const handleBack = useCallback(() => {\n if (statusOverlay && statusOverlay.type !== 'loading') {\n handleStatusDismiss()\n return\n }\n switch (phase.type) {\n case 'main':\n onDone()\n break\n case 'server-actions':\n setPhase({ type: 'main' })\n setSearchQuery('')\n break\n case 'confirm-delete':\n setPhase({\n type: 'server-actions',\n serverName: phase.serverName,\n scope: phase.scope,\n })\n break\n case 'add-name':\n case 'add-command':\n setPhase({ type: 'main' })\n setSearchQuery('')\n break\n }\n }, [phase, statusOverlay, onDone, handleStatusDismiss])\n\n const handleClose = useCallback(() => {\n if (statusOverlay && statusOverlay.type !== 'loading') {\n handleStatusDismiss()\n return\n }\n if (phase.type === 'main') {\n onDone()\n } else {\n setPhase({ type: 'main' })\n setSearchQuery('')\n }\n }, [phase, statusOverlay, onDone, handleStatusDismiss])\n\n // \u2500\u2500\u2500 Handle search submit (for add-name / add-command) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const handleSearchSubmit = useCallback(\n async (query: string) => {\n if (!query.trim()) return\n\n if (phase.type === 'add-name') {\n setPhase({ type: 'add-command', name: query.trim() })\n setSearchQuery('')\n return\n }\n\n if (phase.type === 'add-command') {\n await addNewServer(phase.name, query.trim())\n setSearchQuery('')\n }\n },\n [phase, addNewServer],\n )\n\n // \u2500\u2500\u2500 Handle item selection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const handleSelect = useCallback(\n async (item: ListItem) => {\n switch (phase.type) {\n case 'main': {\n if (item.id === ID_ADD_SERVER) {\n setPhase({ type: 'add-name' })\n setSearchQuery('')\n return\n }\n if (item.id === ID_REFRESH_ALL) {\n await refreshAll()\n return\n }\n // Server selected \u2014 go to actions\n const data = item.data as { type: string; server?: ServerStatus }\n if (data.type === 'server' && data.server) {\n setPhase({\n type: 'server-actions',\n serverName: data.server.name,\n scope: data.server.config.scope,\n })\n }\n break\n }\n\n case 'server-actions': {\n if (item.id === ID_BACK) {\n setPhase({ type: 'main' })\n return\n }\n if (item.id === ID_TOGGLE) {\n await toggleServer(phase.serverName)\n return\n }\n if (item.id === ID_DELETE) {\n setPhase({\n type: 'confirm-delete',\n serverName: phase.serverName,\n scope: phase.scope,\n })\n }\n break\n }\n\n case 'confirm-delete': {\n if (item.id === ID_CONFIRM_YES) {\n await deleteServer(phase.serverName, phase.scope)\n } else {\n // No \u2014 back to actions\n setPhase({\n type: 'server-actions',\n serverName: phase.serverName,\n scope: phase.scope,\n })\n }\n break\n }\n\n case 'add-command': {\n // Clicking an example copies label to search\n setSearchQuery(item.label)\n break\n }\n }\n },\n [phase, refreshAll, toggleServer, deleteServer],\n )\n\n // \u2500\u2500\u2500 Determine current tab for rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const currentTab =\n phase.type === 'main'\n ? activeTab\n : phase.type === 'server-actions' || phase.type === 'confirm-delete'\n ? 'actions'\n : 'add'\n\n // \u2500\u2500\u2500 Determine if search submit is needed \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const needsSearchSubmit =\n phase.type === 'add-name' || phase.type === 'add-command'\n\n return (\n <TabbedListView\n title={title}\n tabs={tabs}\n activeTab={currentTab}\n onTabChange={handleTabChange}\n items={items}\n searchEnabled={searchEnabled}\n searchPlaceholder={searchPlaceholder}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onSearchSubmit={needsSearchSubmit ? handleSearchSubmit : undefined}\n onSelect={handleSelect}\n onClose={handleClose}\n onBack={handleBack}\n statusOverlay={statusOverlay}\n footerHint={footerHint}\n groupByCategory={false}\n isLoading={loading}\n emptyText={t('commands.mcp.noServers')}\n statusDismissHint=\"Enter Continue \u00B7 Esc Back\"\n />\n )\n}\n\n// =============================================================================\n// Command Definition\n// =============================================================================\n\nconst mcpInteractive = {\n type: 'local-jsx',\n name: 'mcp',\n description: t('commands.mcp.description'),\n isEnabled: true,\n isHidden: false,\n hidePromptInput: true,\n async call(onDone: (result?: string) => void) {\n return <MCPInteractive onDone={onDone} />\n },\n userFacingName() {\n return 'mcp'\n },\n} satisfies Command\n\nexport default mcpInteractive\n"],
5
+ "mappings": "AAaA,OAAO,SAAS,UAAU,WAAW,aAAa,eAAe;AAEjE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAM/B,SAAS,SAAS;AAoBlB,MAAM,gBAAgB;AACtB,MAAM,iBAAiB;AACvB,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,UAAU;AAChB,MAAM,iBAAiB;AACvB,MAAM,gBAAgB;AAMtB,MAAM,iBAED,CAAC,EAAE,OAAO,MAAM;AACnB,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAmB,EAAE,MAAM,OAAO,CAAC;AAC7D,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,EAAE;AACjD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAA+B,IAAI;AAC7E,QAAM,CAAC,SAAS,UAAU,IAAI,SAAyB,CAAC,CAAC;AACzD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAG3C,QAAM,cAAc,YAAY,YAAY;AAC1C,QAAI;AACF,YAAM,gBAAgB,eAAe;AACrC,YAAM,UAAU,MAAM,WAAW;AAEjC,YAAM,iBAAiC,OAAO,QAAQ,aAAa,EAAE;AAAA,QACnE,CAAC,CAAC,MAAM,CAAC,MAAM;AACb,gBAAM,SAAS,QAAQ,KAAK,OAAK,EAAE,SAAS,IAAI;AAChD,gBAAM,SAAS,aAAa,IAAI;AAChC,iBAAO;AAAA,YACL;AAAA,YACA,QAAQ,QAAQ,SAAS,cAAc,cAAc;AAAA,YACrD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,iBAAW,cAAc;AAAA,IAC3B,QAAQ;AACN,iBAAW,CAAC,CAAC;AAAA,IACf;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACd,eAAW,IAAI;AACf,gBAAY,EAAE,QAAQ,MAAM,WAAW,KAAK,CAAC;AAAA,EAC/C,GAAG,CAAC,WAAW,CAAC;AAGhB,YAAU,MAAM;AACd,QAAI,MAAM,SAAS,QAAQ;AACzB,kBAAY;AACZ,qBAAe,EAAE;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,OAAO,WAAW,CAAC;AAIvB,QAAM,eAAe;AAAA,IACnB,OAAO,eAAuB;AAC5B,uBAAiB;AAAA,QACf,MAAM;AAAA,QACN,SAAS,EAAE,uBAAuB;AAAA,MACpC,CAAC;AACD,UAAI;AACF,cAAM,gBAAgB,wBAAwB;AAC9C,cAAM,gBAAgB,cAAc,aAAa,UAAU;AAE3D,YAAI,eAAe;AACjB,gBAAM,aAAa,EAAE,cAAc,WAAW;AAC9C,gBAAM,yBAAyB;AAAA,YAC7B,GAAG;AAAA,YACH,YAAY;AAAA,cACV,GAAG,cAAc;AAAA,cACjB,CAAC,UAAU,GAAG,EAAE,GAAG,eAAe,SAAS,WAAW;AAAA,YACxD;AAAA,UACF,CAAC;AAAA,QACH,OAAO;AACL,gBAAM,eAAe,aAAa,UAAU;AAC5C,cAAI,cAAc;AAChB,kBAAM,yBAAyB;AAAA,cAC7B,GAAG;AAAA,cACH,YAAY;AAAA,gBACV,GAAG,cAAc;AAAA,gBACjB,CAAC,UAAU,GAAG,EAAE,GAAG,cAAc,SAAS,MAAM;AAAA,cAClD;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAEA,cAAM,sBAAsB;AAC5B,cAAM,YAAY;AAClB,yBAAiB;AAAA,UACf,MAAM;AAAA,UACN,SAAS,EAAE,4BAA4B;AAAA,QACzC,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,yBAAiB,EAAE,MAAM,SAAS,SAAS,IAAI,CAAC;AAAA,MAClD;AAAA,IACF;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,eAAe;AAAA,IACnB,OAAO,YAAoB,UAAkB;AAC3C,uBAAiB;AAAA,QACf,MAAM;AAAA,QACN,SAAS,EAAE,uBAAuB;AAAA,MACpC,CAAC;AACD,UAAI;AACF,wBAAgB,YAAY,KAA6B;AACzD,cAAM,sBAAsB;AAC5B,cAAM,YAAY;AAClB,yBAAiB;AAAA,UACf,MAAM;AAAA,UACN,SAAS,EAAE,4BAA4B;AAAA,QACzC,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,yBAAiB,EAAE,MAAM,SAAS,SAAS,IAAI,CAAC;AAAA,MAClD;AAAA,IACF;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,eAAe;AAAA,IACnB,OAAO,MAAc,iBAAyB;AAC5C,uBAAiB;AAAA,QACf,MAAM;AAAA,QACN,SAAS,EAAE,qBAAqB;AAAA,MAClC,CAAC;AACD,UAAI;AACF,YACE,aAAa,WAAW,SAAS,KACjC,aAAa,WAAW,UAAU,GAClC;AACA,uBAAa,MAAM,EAAE,MAAM,OAAO,KAAK,aAAa,GAAG,SAAS;AAAA,QAClE,OAAO;AACL,gBAAM,QAAQ,aAAa,MAAM,KAAK;AACtC,gBAAM,UAAU,MAAM,CAAC;AACvB,gBAAM,OAAO,MAAM,MAAM,CAAC;AAC1B;AAAA,YACE;AAAA,YACA,EAAE,MAAM,SAAS,SAAS,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,EAAE;AAAA,YAC5D;AAAA,UACF;AAAA,QACF;AACA,cAAM,sBAAsB;AAC5B,cAAM,YAAY;AAClB,yBAAiB;AAAA,UACf,MAAM;AAAA,UACN,SAAS,EAAE,yBAAyB;AAAA,QACtC,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,yBAAiB;AAAA,UACf,MAAM;AAAA,UACN,SAAS,GAAG,EAAE,wBAAwB,CAAC,KAAK,GAAG;AAAA,QACjD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,aAAa,YAAY,YAAY;AACzC,qBAAiB;AAAA,MACf,MAAM;AAAA,MACN,SAAS,EAAE,yBAAyB;AAAA,IACtC,CAAC;AACD,QAAI;AACF,YAAM,sBAAsB;AAC5B,YAAM,YAAY;AAElB,uBAAiB,IAAI;AAAA,IACvB,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,uBAAiB,EAAE,MAAM,SAAS,SAAS,IAAI,CAAC;AAAA,IAClD;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAIhB,QAAM,EAAE,MAAM,OAAO,OAAO,YAAY,eAAe,kBAAkB,IACvE,QAAQ,MAAM;AACZ,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK,QAAQ;AACX,cAAM,eAAe,QAAQ;AAAA,UAC3B,OAAK,EAAE,OAAO,UAAU;AAAA,QAC1B,EAAE;AACF,cAAM,cAAc,QAAQ;AAAA,UAC1B,OAAK,EAAE,OAAO,UAAU;AAAA,QAC1B,EAAE;AAEF,cAAM,WAA4B;AAAA,UAChC;AAAA,YACE,IAAI;AAAA,YACJ,OAAO,EAAE,qBAAqB;AAAA,YAC9B,OAAO,QAAQ;AAAA,UACjB;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OAAO,EAAE,yBAAyB;AAAA,YAClC,OAAO;AAAA,UACT;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OAAO,EAAE,wBAAwB;AAAA,YACjC,OAAO;AAAA,UACT;AAAA,QACF;AAGA,cAAM,WACJ,cAAc,QACV,UACA,QAAQ,OAAO,OAAK,EAAE,OAAO,UAAU,SAAS;AAEtD,cAAM,YAAwB,SAAS,IAAI,YAAU;AACnD,gBAAM,YACJ,aAAa,OAAO,SAAS,OAAO,OAAO,UAAU;AACvD,iBAAO;AAAA,YACL,IAAI,OAAO;AAAA,YACX,OAAO,OAAO;AAAA,YACd,aAAa,GAAG,OAAO,OAAO,KAAK,SAAM,OAAO,OAAO,IAAI;AAAA,YAC3D,QAAQ,CAAC,YACL,aACA,OAAO,WAAW,cAChB,YACA;AAAA,YACN,MAAM,EAAE,MAAM,UAAU,OAAO;AAAA,UACjC;AAAA,QACF,CAAC;AAGD,kBAAU,KAAK;AAAA,UACb,IAAI;AAAA,UACJ,OAAO,KAAK,EAAE,wBAAwB,CAAC;AAAA,UACvC,MAAM,EAAE,MAAM,SAAS;AAAA,QACzB,CAAC;AACD,kBAAU,KAAK;AAAA,UACb,IAAI;AAAA,UACJ,OAAO,UAAK,EAAE,yBAAyB,CAAC;AAAA,UACxC,MAAM,EAAE,MAAM,SAAS;AAAA,QACzB,CAAC;AAED,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,OAAO,EAAE,oBAAoB;AAAA,UAC7B,YACE;AAAA,UACF,eAAe;AAAA,UACf,mBAAmB;AAAA,QACrB;AAAA,MACF;AAAA,MAEA,KAAK,kBAAkB;AACrB,cAAM,SAAS,QAAQ,KAAK,OAAK,EAAE,SAAS,MAAM,UAAU;AAC5D,cAAM,YAAY,SACd,aAAa,OAAO,SAClB,OAAO,OAAO,UACd,OACF;AAEJ,cAAM,cAA0B;AAAA,UAC9B;AAAA,YACE,IAAI;AAAA,YACJ,OAAO,YACH,EAAE,sBAAsB,IACxB,EAAE,qBAAqB;AAAA,UAC7B;AAAA,UACA,EAAE,IAAI,WAAW,OAAO,EAAE,2BAA2B,EAAE;AAAA,UACvD,EAAE,IAAI,SAAS,OAAO,UAAK,EAAE,mBAAmB,CAAC,GAAG;AAAA,QACtD;AAEA,eAAO;AAAA,UACL,MAAM;AAAA,YACJ,EAAE,IAAI,WAAW,OAAO,EAAE,sBAAsB,EAAE;AAAA,UACpD;AAAA,UACA,OAAO;AAAA,UACP,OAAO,MAAM;AAAA,UACb,YAAY;AAAA,UACZ,eAAe;AAAA,UACf,mBAAmB;AAAA,QACrB;AAAA,MACF;AAAA,MAEA,KAAK,kBAAkB;AACrB,cAAM,eAA2B;AAAA,UAC/B,EAAE,IAAI,gBAAgB,OAAO,EAAE,yBAAyB,EAAE;AAAA,UAC1D,EAAE,IAAI,eAAe,OAAO,EAAE,wBAAwB,EAAE;AAAA,QAC1D;AAEA,eAAO;AAAA,UACL,MAAM;AAAA,YACJ,EAAE,IAAI,WAAW,OAAO,EAAE,sBAAsB,EAAE;AAAA,UACpD;AAAA,UACA,OAAO;AAAA,UACP,OAAO,EAAE,iCAAiC,EAAE;AAAA,YAC1C;AAAA,YACA,MAAM;AAAA,UACR;AAAA,UACA,YAAY;AAAA,UACZ,eAAe;AAAA,UACf,mBAAmB;AAAA,QACrB;AAAA,MACF;AAAA,MAEA,KAAK,YAAY;AACf,eAAO;AAAA,UACL,MAAM;AAAA,YACJ,EAAE,IAAI,OAAO,OAAO,EAAE,wBAAwB,EAAE;AAAA,UAClD;AAAA,UACA,OAAO,CAAC;AAAA,UACR,OAAO,EAAE,wBAAwB;AAAA,UACjC,YAAY,EAAE,4BAA4B;AAAA,UAC1C,eAAe;AAAA,UACf,mBAAmB,EAAE,iCAAiC;AAAA,QACxD;AAAA,MACF;AAAA,MAEA,KAAK,eAAe;AAClB,cAAM,eAA2B;AAAA,UAC/B;AAAA,YACE,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,UACf;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,UACf;AAAA,QACF;AAEA,eAAO;AAAA,UACL,MAAM;AAAA,YACJ,EAAE,IAAI,OAAO,OAAO,EAAE,wBAAwB,EAAE;AAAA,UAClD;AAAA,UACA,OAAO;AAAA,UACP,OAAO,GAAG,EAAE,wBAAwB,CAAC,KAAK,MAAM,IAAI;AAAA,UACpD,YAAY,EAAE,mCAAmC;AAAA,UACjD,eAAe;AAAA,UACf,mBAAmB,EAAE,oCAAoC;AAAA,QAC3D;AAAA,MACF;AAAA,MACA;AACE,eAAO;AAAA,UACL,MAAM,CAAC;AAAA,UACP,OAAO,CAAC;AAAA,UACR,OAAO;AAAA,UACP,YAAY;AAAA,UACZ,eAAe;AAAA,UACf,mBAAmB;AAAA,QACrB;AAAA,IACJ;AAAA,EACF,GAAG,CAAC,OAAO,WAAW,OAAO,CAAC;AAIhC,QAAM,kBAAkB,YAAY,CAAC,UAAkB;AACrD,iBAAa,KAAK;AAClB,mBAAe,EAAE;AAAA,EACnB,GAAG,CAAC,CAAC;AAIL,QAAM,sBAAsB,YAAY,MAAM;AAC5C,qBAAiB,IAAI;AACrB,aAAS,EAAE,MAAM,OAAO,CAAC;AAAA,EAC3B,GAAG,CAAC,CAAC;AAIL,QAAM,aAAa,YAAY,MAAM;AACnC,QAAI,iBAAiB,cAAc,SAAS,WAAW;AACrD,0BAAoB;AACpB;AAAA,IACF;AACA,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH,eAAO;AACP;AAAA,MACF,KAAK;AACH,iBAAS,EAAE,MAAM,OAAO,CAAC;AACzB,uBAAe,EAAE;AACjB;AAAA,MACF,KAAK;AACH,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,YAAY,MAAM;AAAA,UAClB,OAAO,MAAM;AAAA,QACf,CAAC;AACD;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,iBAAS,EAAE,MAAM,OAAO,CAAC;AACzB,uBAAe,EAAE;AACjB;AAAA,IACJ;AAAA,EACF,GAAG,CAAC,OAAO,eAAe,QAAQ,mBAAmB,CAAC;AAEtD,QAAM,cAAc,YAAY,MAAM;AACpC,QAAI,iBAAiB,cAAc,SAAS,WAAW;AACrD,0BAAoB;AACpB;AAAA,IACF;AACA,QAAI,MAAM,SAAS,QAAQ;AACzB,aAAO;AAAA,IACT,OAAO;AACL,eAAS,EAAE,MAAM,OAAO,CAAC;AACzB,qBAAe,EAAE;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,OAAO,eAAe,QAAQ,mBAAmB,CAAC;AAItD,QAAM,qBAAqB;AAAA,IACzB,OAAO,UAAkB;AACvB,UAAI,CAAC,MAAM,KAAK,EAAG;AAEnB,UAAI,MAAM,SAAS,YAAY;AAC7B,iBAAS,EAAE,MAAM,eAAe,MAAM,MAAM,KAAK,EAAE,CAAC;AACpD,uBAAe,EAAE;AACjB;AAAA,MACF;AAEA,UAAI,MAAM,SAAS,eAAe;AAChC,cAAM,aAAa,MAAM,MAAM,MAAM,KAAK,CAAC;AAC3C,uBAAe,EAAE;AAAA,MACnB;AAAA,IACF;AAAA,IACA,CAAC,OAAO,YAAY;AAAA,EACtB;AAIA,QAAM,eAAe;AAAA,IACnB,OAAO,SAAmB;AACxB,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK,QAAQ;AACX,cAAI,KAAK,OAAO,eAAe;AAC7B,qBAAS,EAAE,MAAM,WAAW,CAAC;AAC7B,2BAAe,EAAE;AACjB;AAAA,UACF;AACA,cAAI,KAAK,OAAO,gBAAgB;AAC9B,kBAAM,WAAW;AACjB;AAAA,UACF;AAEA,gBAAM,OAAO,KAAK;AAClB,cAAI,KAAK,SAAS,YAAY,KAAK,QAAQ;AACzC,qBAAS;AAAA,cACP,MAAM;AAAA,cACN,YAAY,KAAK,OAAO;AAAA,cACxB,OAAO,KAAK,OAAO,OAAO;AAAA,YAC5B,CAAC;AAAA,UACH;AACA;AAAA,QACF;AAAA,QAEA,KAAK,kBAAkB;AACrB,cAAI,KAAK,OAAO,SAAS;AACvB,qBAAS,EAAE,MAAM,OAAO,CAAC;AACzB;AAAA,UACF;AACA,cAAI,KAAK,OAAO,WAAW;AACzB,kBAAM,aAAa,MAAM,UAAU;AACnC;AAAA,UACF;AACA,cAAI,KAAK,OAAO,WAAW;AACzB,qBAAS;AAAA,cACP,MAAM;AAAA,cACN,YAAY,MAAM;AAAA,cAClB,OAAO,MAAM;AAAA,YACf,CAAC;AAAA,UACH;AACA;AAAA,QACF;AAAA,QAEA,KAAK,kBAAkB;AACrB,cAAI,KAAK,OAAO,gBAAgB;AAC9B,kBAAM,aAAa,MAAM,YAAY,MAAM,KAAK;AAAA,UAClD,OAAO;AAEL,qBAAS;AAAA,cACP,MAAM;AAAA,cACN,YAAY,MAAM;AAAA,cAClB,OAAO,MAAM;AAAA,YACf,CAAC;AAAA,UACH;AACA;AAAA,QACF;AAAA,QAEA,KAAK,eAAe;AAElB,yBAAe,KAAK,KAAK;AACzB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,OAAO,YAAY,cAAc,YAAY;AAAA,EAChD;AAIA,QAAM,aACJ,MAAM,SAAS,SACX,YACA,MAAM,SAAS,oBAAoB,MAAM,SAAS,mBAChD,YACA;AAIR,QAAM,oBACJ,MAAM,SAAS,cAAc,MAAM,SAAS;AAE9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,gBAAgB,oBAAoB,qBAAqB;AAAA,MACzD,UAAU;AAAA,MACV,SAAS;AAAA,MACT,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,WAAW,EAAE,wBAAwB;AAAA,MACrC,mBAAkB;AAAA;AAAA,EACpB;AAEJ;AAMA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa,EAAE,0BAA0B;AAAA,EACzC,WAAW;AAAA,EACX,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,MAAM,KAAK,QAAmC;AAC5C,WAAO,oCAAC,kBAAe,QAAgB;AAAA,EACzC;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AACF;AAEA,IAAO,0BAAQ;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,168 @@
1
+ import { existsSync, writeFileSync, mkdirSync, openSync, closeSync } from "fs";
2
+ import { join, dirname } from "path";
3
+ import { execSync, spawnSync } from "child_process";
4
+ import { platform as osPlatform, userInfo } from "os";
5
+ import * as net from "net";
6
+ import { getCwd } from "../utils/state.js";
7
+ import { PRODUCT_NAME } from "../constants/product.js";
8
+ const TEMPLATE = `# ${PRODUCT_NAME} Project Instructions
9
+
10
+ <!-- Add project-specific instructions here. These will be included in every conversation. -->
11
+
12
+ ## Project Overview
13
+
14
+
15
+ ## Coding Conventions
16
+
17
+
18
+ ## Important Notes
19
+
20
+ `;
21
+ function getAiTerSocketPath() {
22
+ if (osPlatform() === "win32") {
23
+ const username = userInfo().username;
24
+ return `\\\\.\\pipe\\aiter-${username}`;
25
+ }
26
+ const uid = process.getuid?.() ?? userInfo().uid;
27
+ return `/tmp/aiter-${uid}.sock`;
28
+ }
29
+ function isAiTerRunning() {
30
+ const socketPath = getAiTerSocketPath();
31
+ if (osPlatform() !== "win32" && !existsSync(socketPath)) {
32
+ return false;
33
+ }
34
+ return true;
35
+ }
36
+ function openInAiTer(filePath) {
37
+ return new Promise((resolve) => {
38
+ const socketPath = getAiTerSocketPath();
39
+ const request = JSON.stringify({
40
+ command: "editor",
41
+ action: "open",
42
+ params: { filePath, mode: "edit" }
43
+ });
44
+ const socket = net.createConnection(socketPath);
45
+ let buffer = "";
46
+ const timeout = setTimeout(() => {
47
+ socket.destroy();
48
+ resolve(false);
49
+ }, 3e3);
50
+ socket.on("connect", () => {
51
+ socket.write(request + "\n");
52
+ });
53
+ socket.on("data", (chunk) => {
54
+ buffer += chunk.toString();
55
+ try {
56
+ const response = JSON.parse(buffer);
57
+ clearTimeout(timeout);
58
+ socket.end();
59
+ resolve(response.success === true);
60
+ } catch {
61
+ }
62
+ });
63
+ socket.on("error", () => {
64
+ clearTimeout(timeout);
65
+ resolve(false);
66
+ });
67
+ });
68
+ }
69
+ const TERMINAL_EDITORS = /^(vi|vim|nvim|nano|emacs|pico|ed|micro|helix|hx|kak)$/i;
70
+ function openInTerminalEditor(editor, filePath) {
71
+ let ttyFd;
72
+ try {
73
+ ttyFd = openSync("/dev/tty", "r");
74
+ } catch {
75
+ ttyFd = void 0;
76
+ }
77
+ if (typeof process.stdin.setRawMode === "function") {
78
+ process.stdin.setRawMode(false);
79
+ }
80
+ process.stdin.pause();
81
+ try {
82
+ const result = spawnSync(editor, [filePath], {
83
+ stdio: [ttyFd ?? "inherit", "inherit", "inherit"],
84
+ shell: false
85
+ });
86
+ if (result.error) {
87
+ throw new Error(`Failed to open editor: ${result.error.message}`);
88
+ }
89
+ } finally {
90
+ if (ttyFd !== void 0) {
91
+ try {
92
+ closeSync(ttyFd);
93
+ } catch {
94
+ }
95
+ }
96
+ process.stdin.resume();
97
+ if (typeof process.stdin.setRawMode === "function") {
98
+ process.stdin.setRawMode(true);
99
+ }
100
+ process.stdout.emit("resize");
101
+ }
102
+ }
103
+ function getPlatformDefaultEditor() {
104
+ if (osPlatform() === "win32") return "notepad";
105
+ return "vi";
106
+ }
107
+ const memory = {
108
+ name: "memory",
109
+ description: "Open project instructions file (MINTO.md) in your editor",
110
+ isEnabled: true,
111
+ isHidden: false,
112
+ type: "local",
113
+ userFacingName() {
114
+ return "memory";
115
+ },
116
+ async call() {
117
+ const cwd = getCwd();
118
+ let filePath = join(cwd, "MINTO.md");
119
+ if (!existsSync(filePath)) {
120
+ const agentsPath = join(cwd, "AGENTS.md");
121
+ if (existsSync(agentsPath)) {
122
+ filePath = agentsPath;
123
+ } else {
124
+ const claudePath = join(cwd, "CLAUDE.md");
125
+ if (existsSync(claudePath)) {
126
+ filePath = claudePath;
127
+ }
128
+ }
129
+ }
130
+ if (!existsSync(filePath)) {
131
+ const dir = dirname(filePath);
132
+ if (!existsSync(dir)) {
133
+ mkdirSync(dir, { recursive: true });
134
+ }
135
+ writeFileSync(filePath, TEMPLATE, "utf-8");
136
+ }
137
+ if (isAiTerRunning()) {
138
+ try {
139
+ const success = await openInAiTer(filePath);
140
+ if (success) {
141
+ return `Opened ${filePath} in AiTer editor. Changes will take effect in the next conversation.`;
142
+ }
143
+ } catch {
144
+ }
145
+ }
146
+ const envEditor = process.env.VISUAL || process.env.EDITOR;
147
+ const editor = envEditor || getPlatformDefaultEditor();
148
+ const editorBin = editor.split("/").pop() || editor;
149
+ try {
150
+ if (TERMINAL_EDITORS.test(editorBin)) {
151
+ openInTerminalEditor(editor, filePath);
152
+ } else {
153
+ execSync(`${editor} ${JSON.stringify(filePath)}`, {
154
+ stdio: "ignore",
155
+ timeout: 5e3
156
+ });
157
+ }
158
+ return `Opened ${filePath} in ${editorBin}. Changes will take effect in the next conversation.`;
159
+ } catch (error) {
160
+ return `Failed to open editor (${editorBin}): ${error instanceof Error ? error.message : String(error)}`;
161
+ }
162
+ }
163
+ };
164
+ var memory_default = memory;
165
+ export {
166
+ memory_default as default
167
+ };
168
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/commands/memory.ts"],
4
+ "sourcesContent": ["/**\n * /memory command\n *\n * Opens MINTO.md (or CLAUDE.md) for editing.\n *\n * Editor selection priority:\n * 1. AiTer (if running) \u2014 best experience, uses AiTer's built-in editor\n * 2. $VISUAL / $EDITOR (if set) \u2014 respects user preference\n * 3. Platform default \u2014 vi (macOS/Linux), notepad (Windows)\n *\n * For terminal editors (vi/vim/nano/emacs), properly releases Ink's TTY\n * and restores it after the editor exits.\n */\n\nimport { existsSync, writeFileSync, mkdirSync, openSync, closeSync } from 'fs'\nimport { join, dirname } from 'path'\nimport { execSync, spawnSync } from 'child_process'\nimport { platform as osPlatform, userInfo } from 'os'\nimport * as net from 'net'\nimport { getCwd } from '@utils/state'\nimport { PRODUCT_NAME } from '@constants/product'\nimport type { Command } from '../commands'\n\nconst TEMPLATE = `# ${PRODUCT_NAME} Project Instructions\n\n<!-- Add project-specific instructions here. These will be included in every conversation. -->\n\n## Project Overview\n\n\n## Coding Conventions\n\n\n## Important Notes\n\n`\n\n// \u2500\u2500\u2500 AiTer Integration \u2500\u2500\u2500\n\n/**\n * Get AiTer CLI socket path (must match AiTer's getSocketPath()).\n */\nfunction getAiTerSocketPath(): string {\n if (osPlatform() === 'win32') {\n const username = userInfo().username\n return `\\\\\\\\.\\\\pipe\\\\aiter-${username}`\n }\n const uid = process.getuid?.() ?? userInfo().uid\n return `/tmp/aiter-${uid}.sock`\n}\n\n/**\n * Check if AiTer is running by testing the socket.\n */\nfunction isAiTerRunning(): boolean {\n const socketPath = getAiTerSocketPath()\n if (osPlatform() !== 'win32' && !existsSync(socketPath)) {\n return false\n }\n return true\n}\n\n/**\n * Open a file in AiTer's editor via CLI socket.\n * Returns true on success, false on failure.\n */\nfunction openInAiTer(filePath: string): Promise<boolean> {\n return new Promise(resolve => {\n const socketPath = getAiTerSocketPath()\n const request = JSON.stringify({\n command: 'editor',\n action: 'open',\n params: { filePath, mode: 'edit' },\n })\n\n const socket = net.createConnection(socketPath)\n let buffer = ''\n\n const timeout = setTimeout(() => {\n socket.destroy()\n resolve(false)\n }, 3000)\n\n socket.on('connect', () => {\n socket.write(request + '\\n')\n })\n\n socket.on('data', chunk => {\n buffer += chunk.toString()\n try {\n const response = JSON.parse(buffer)\n clearTimeout(timeout)\n socket.end()\n resolve(response.success === true)\n } catch {\n // Incomplete JSON, wait for more data\n }\n })\n\n socket.on('error', () => {\n clearTimeout(timeout)\n resolve(false)\n })\n })\n}\n\n// \u2500\u2500\u2500 Terminal Editor (TTY-safe) \u2500\u2500\u2500\n\nconst TERMINAL_EDITORS = /^(vi|vim|nvim|nano|emacs|pico|ed|micro|helix|hx|kak)$/i\n\n/**\n * Open file in a terminal editor with proper TTY management.\n * Releases Ink's raw mode, blocks until editor exits, restores state.\n */\nfunction openInTerminalEditor(editor: string, filePath: string): void {\n // Open /dev/tty for keyboard input (bypasses Ink's stdin)\n let ttyFd: number | undefined\n try {\n ttyFd = openSync('/dev/tty', 'r')\n } catch {\n ttyFd = undefined\n }\n\n // Release Ink's raw mode\n if (typeof process.stdin.setRawMode === 'function') {\n process.stdin.setRawMode(false)\n }\n process.stdin.pause()\n\n try {\n const result = spawnSync(editor, [filePath], {\n stdio: [ttyFd ?? 'inherit', 'inherit', 'inherit'],\n shell: false,\n })\n if (result.error) {\n throw new Error(`Failed to open editor: ${result.error.message}`)\n }\n } finally {\n if (ttyFd !== undefined) {\n try {\n closeSync(ttyFd)\n } catch {\n // Ignore\n }\n }\n // Restore Ink state\n process.stdin.resume()\n if (typeof process.stdin.setRawMode === 'function') {\n process.stdin.setRawMode(true)\n }\n process.stdout.emit('resize')\n }\n}\n\n// \u2500\u2500\u2500 Platform Default Editors \u2500\u2500\u2500\n\nfunction getPlatformDefaultEditor(): string {\n if (osPlatform() === 'win32') return 'notepad'\n return 'vi' // macOS and Linux always have vi\n}\n\n// \u2500\u2500\u2500 Command Implementation \u2500\u2500\u2500\n\nconst memory: Command = {\n name: 'memory',\n description: 'Open project instructions file (MINTO.md) in your editor',\n isEnabled: true,\n isHidden: false,\n type: 'local',\n userFacingName() {\n return 'memory'\n },\n async call() {\n const cwd = getCwd()\n\n // Find existing file: MINTO.md > AGENTS.md > CLAUDE.md\n let filePath = join(cwd, 'MINTO.md')\n if (!existsSync(filePath)) {\n const agentsPath = join(cwd, 'AGENTS.md')\n if (existsSync(agentsPath)) {\n filePath = agentsPath\n } else {\n const claudePath = join(cwd, 'CLAUDE.md')\n if (existsSync(claudePath)) {\n filePath = claudePath\n }\n }\n }\n\n // Create MINTO.md with template if neither exists\n if (!existsSync(filePath)) {\n const dir = dirname(filePath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n writeFileSync(filePath, TEMPLATE, 'utf-8')\n }\n\n // Strategy 1: Try AiTer first\n if (isAiTerRunning()) {\n try {\n const success = await openInAiTer(filePath)\n if (success) {\n return `Opened ${filePath} in AiTer editor. Changes will take effect in the next conversation.`\n }\n } catch {\n // AiTer failed, fall through\n }\n }\n\n // Strategy 2: Use $VISUAL or $EDITOR\n const envEditor = process.env.VISUAL || process.env.EDITOR\n const editor = envEditor || getPlatformDefaultEditor()\n const editorBin = editor.split('/').pop() || editor\n\n try {\n if (TERMINAL_EDITORS.test(editorBin)) {\n // Terminal editor \u2014 needs TTY management\n openInTerminalEditor(editor, filePath)\n } else {\n // GUI editor \u2014 non-blocking exec\n execSync(`${editor} ${JSON.stringify(filePath)}`, {\n stdio: 'ignore',\n timeout: 5000,\n })\n }\n return `Opened ${filePath} in ${editorBin}. Changes will take effect in the next conversation.`\n } catch (error) {\n return `Failed to open editor (${editorBin}): ${error instanceof Error ? error.message : String(error)}`\n }\n },\n}\n\nexport default memory\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }