@within-7/minto 0.1.5 → 0.1.6

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 (264) hide show
  1. package/dist/commands/agents/AgentsCommand.js +2342 -0
  2. package/dist/commands/agents/AgentsCommand.js.map +7 -0
  3. package/dist/commands/agents/constants.js +58 -0
  4. package/dist/commands/agents/constants.js.map +7 -0
  5. package/dist/commands/agents/index.js +37 -0
  6. package/dist/commands/agents/index.js.map +7 -0
  7. package/dist/commands/agents/types.js +10 -0
  8. package/dist/commands/agents/types.js.map +7 -0
  9. package/dist/commands/agents/utils/fileOperations.js +185 -0
  10. package/dist/commands/agents/utils/fileOperations.js.map +7 -0
  11. package/dist/commands/agents/utils/index.js +21 -0
  12. package/dist/commands/agents/utils/index.js.map +7 -0
  13. package/dist/commands/bug.js +2 -2
  14. package/dist/commands/bug.js.map +2 -2
  15. package/dist/commands/compact.js +5 -5
  16. package/dist/commands/compact.js.map +2 -2
  17. package/dist/commands/ctx_viz.js +55 -22
  18. package/dist/commands/ctx_viz.js.map +2 -2
  19. package/dist/commands/mcp-interactive.js +11 -11
  20. package/dist/commands/mcp-interactive.js.map +2 -2
  21. package/dist/commands/model.js +94 -32
  22. package/dist/commands/model.js.map +3 -3
  23. package/dist/commands/plugin/AddMarketplaceForm.js +49 -21
  24. package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
  25. package/dist/commands/plugin/ConfirmDialog.js +38 -26
  26. package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
  27. package/dist/commands/plugin/InstalledPluginsByMarketplace.js +24 -8
  28. package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
  29. package/dist/commands/plugin/InstalledPluginsManager.js +3 -1
  30. package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
  31. package/dist/commands/plugin/MainMenu.js +16 -7
  32. package/dist/commands/plugin/MainMenu.js.map +2 -2
  33. package/dist/commands/plugin/MarketplaceManager.js +84 -39
  34. package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
  35. package/dist/commands/plugin/MarketplaceSelector.js +7 -3
  36. package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
  37. package/dist/commands/plugin/PlaceholderScreen.js +16 -2
  38. package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
  39. package/dist/commands/plugin/PluginBrowser.js +4 -2
  40. package/dist/commands/plugin/PluginBrowser.js.map +2 -2
  41. package/dist/commands/plugin/PluginDetailsInstall.js +12 -6
  42. package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
  43. package/dist/commands/plugin/PluginDetailsManage.js +14 -5
  44. package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
  45. package/dist/commands/plugin/example-usage.js.map +2 -2
  46. package/dist/commands/plugin/utils.js.map +2 -2
  47. package/dist/commands/plugin.js +226 -46
  48. package/dist/commands/plugin.js.map +2 -2
  49. package/dist/commands/refreshCommands.js +6 -3
  50. package/dist/commands/refreshCommands.js.map +2 -2
  51. package/dist/commands/resume.js +2 -1
  52. package/dist/commands/resume.js.map +2 -2
  53. package/dist/commands/setup.js +19 -5
  54. package/dist/commands/setup.js.map +2 -2
  55. package/dist/commands/terminalSetup.js +2 -2
  56. package/dist/commands/terminalSetup.js.map +1 -1
  57. package/dist/commands.js +14 -30
  58. package/dist/commands.js.map +2 -2
  59. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
  60. package/dist/components/AskUserQuestionDialog/QuestionView.js +10 -1
  61. package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
  62. package/dist/components/BackgroundTasksPanel.js +5 -1
  63. package/dist/components/BackgroundTasksPanel.js.map +2 -2
  64. package/dist/components/Config.js +17 -4
  65. package/dist/components/Config.js.map +2 -2
  66. package/dist/components/ConsoleOAuthFlow.js.map +2 -2
  67. package/dist/components/CustomSelect/select-option.js +4 -1
  68. package/dist/components/CustomSelect/select-option.js.map +2 -2
  69. package/dist/components/Help.js +6 -8
  70. package/dist/components/Help.js.map +2 -2
  71. package/dist/components/Logo.js +1 -1
  72. package/dist/components/Logo.js.map +2 -2
  73. package/dist/components/ModelListManager.js.map +2 -2
  74. package/dist/components/ModelSelector/ModelSelector.js +2030 -0
  75. package/dist/components/ModelSelector/ModelSelector.js.map +7 -0
  76. package/dist/components/ModelSelector/ScreenContainer.js +27 -0
  77. package/dist/components/ModelSelector/ScreenContainer.js.map +7 -0
  78. package/dist/components/ModelSelector/constants.js +37 -0
  79. package/dist/components/ModelSelector/constants.js.map +7 -0
  80. package/dist/components/ModelSelector/hooks/index.js +5 -0
  81. package/dist/components/ModelSelector/hooks/index.js.map +7 -0
  82. package/dist/components/ModelSelector/hooks/useEscapeNavigation.js +21 -0
  83. package/dist/components/ModelSelector/hooks/useEscapeNavigation.js.map +7 -0
  84. package/dist/components/ModelSelector/index.js +17 -0
  85. package/dist/components/ModelSelector/index.js.map +7 -0
  86. package/dist/components/ModelSelector/types.js +1 -0
  87. package/dist/components/ModelSelector/types.js.map +7 -0
  88. package/dist/components/PressEnterToContinue.js +1 -1
  89. package/dist/components/PressEnterToContinue.js.map +2 -2
  90. package/dist/components/ProjectOnboarding.js +1 -1
  91. package/dist/components/ProjectOnboarding.js.map +2 -2
  92. package/dist/components/PromptInput.js +88 -37
  93. package/dist/components/PromptInput.js.map +2 -2
  94. package/dist/components/QuitSummary.js +17 -10
  95. package/dist/components/QuitSummary.js.map +2 -2
  96. package/dist/components/SentryErrorBoundary.js.map +2 -2
  97. package/dist/components/StreamingBashOutput.js.map +2 -2
  98. package/dist/components/StructuredDiff.js.map +2 -2
  99. package/dist/components/SubagentProgress.js.map +2 -2
  100. package/dist/components/TaskCard.js.map +2 -2
  101. package/dist/components/TextInput.js.map +1 -1
  102. package/dist/components/TodoItem.js.map +1 -1
  103. package/dist/components/binary-feedback/BinaryFeedbackOption.js +1 -3
  104. package/dist/components/binary-feedback/BinaryFeedbackOption.js.map +2 -2
  105. package/dist/components/messages/AssistantLocalCommandOutputMessage.js.map +1 -1
  106. package/dist/components/messages/AssistantToolUseMessage.js +3 -1
  107. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  108. package/dist/components/messages/TaskProgressMessage.js.map +2 -2
  109. package/dist/components/messages/TaskToolMessage.js.map +2 -2
  110. package/dist/components/messages/UserToolResultMessage/utils.js.map +2 -2
  111. package/dist/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js.map +2 -2
  112. package/dist/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js.map +2 -2
  113. package/dist/components/permissions/hooks.js.map +2 -2
  114. package/dist/constants/modelCapabilities.js +1 -1
  115. package/dist/constants/modelCapabilities.js.map +2 -2
  116. package/dist/constants/prompts.js.map +1 -1
  117. package/dist/constants/timing.js +34 -0
  118. package/dist/constants/timing.js.map +7 -0
  119. package/dist/entrypoints/cli.js +128 -33
  120. package/dist/entrypoints/cli.js.map +3 -3
  121. package/dist/entrypoints/mcp.js +13 -18
  122. package/dist/entrypoints/mcp.js.map +2 -2
  123. package/dist/hooks/useCanUseTool.js.map +2 -2
  124. package/dist/hooks/useCancelRequest.js.map +1 -1
  125. package/dist/hooks/useHistorySearch.js.map +2 -2
  126. package/dist/hooks/useLogStartupTime.js.map +2 -2
  127. package/dist/hooks/usePermissionRequestLogging.js.map +2 -2
  128. package/dist/hooks/useTextInput.js.map +1 -1
  129. package/dist/hooks/useUnifiedCompletion.js +493 -394
  130. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  131. package/dist/index.js.map +2 -2
  132. package/dist/permissions.js +4 -7
  133. package/dist/permissions.js.map +2 -2
  134. package/dist/query.js +6 -1
  135. package/dist/query.js.map +2 -2
  136. package/dist/screens/REPL.js +72 -36
  137. package/dist/screens/REPL.js.map +2 -2
  138. package/dist/screens/ResumeConversation.js +2 -1
  139. package/dist/screens/ResumeConversation.js.map +2 -2
  140. package/dist/services/adapters/base.js.map +2 -2
  141. package/dist/services/adapters/chatCompletions.js.map +2 -2
  142. package/dist/services/adapters/responsesAPI.js +3 -1
  143. package/dist/services/adapters/responsesAPI.js.map +2 -2
  144. package/dist/services/claude.js +327 -328
  145. package/dist/services/claude.js.map +2 -2
  146. package/dist/services/customCommands.js +6 -1
  147. package/dist/services/customCommands.js.map +2 -2
  148. package/dist/services/fileFreshness.js.map +2 -2
  149. package/dist/services/gpt5ConnectionTest.js +20 -7
  150. package/dist/services/gpt5ConnectionTest.js.map +2 -2
  151. package/dist/services/hookExecutor.js +6 -12
  152. package/dist/services/hookExecutor.js.map +2 -2
  153. package/dist/services/mcpClient.js +29 -2
  154. package/dist/services/mcpClient.js.map +2 -2
  155. package/dist/services/mentionProcessor.js +23 -10
  156. package/dist/services/mentionProcessor.js.map +2 -2
  157. package/dist/services/modelAdapterFactory.js.map +2 -2
  158. package/dist/services/oauth.js.map +2 -2
  159. package/dist/services/openai.js +109 -72
  160. package/dist/services/openai.js.map +3 -3
  161. package/dist/services/responseStateManager.js.map +2 -2
  162. package/dist/services/systemReminder.js.map +2 -2
  163. package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
  164. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +14 -8
  165. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  166. package/dist/tools/BashOutputTool/BashOutputTool.js.map +2 -2
  167. package/dist/tools/BashTool/BashTool.js.map +2 -2
  168. package/dist/tools/FileReadTool/FileReadTool.js.map +1 -1
  169. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  170. package/dist/tools/GrepTool/GrepTool.js +1 -4
  171. package/dist/tools/GrepTool/GrepTool.js.map +2 -2
  172. package/dist/tools/MultiEditTool/MultiEditTool.js +4 -1
  173. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  174. package/dist/tools/NotebookReadTool/NotebookReadTool.js +3 -1
  175. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
  176. package/dist/tools/SkillTool/SkillTool.js +12 -6
  177. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  178. package/dist/tools/TaskTool/TaskTool.js +14 -5
  179. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  180. package/dist/tools/TaskTool/prompt.js.map +2 -2
  181. package/dist/tools/ThinkTool/ThinkTool.js +6 -1
  182. package/dist/tools/ThinkTool/ThinkTool.js.map +2 -2
  183. package/dist/tools/TodoWriteTool/TodoWriteTool.js +23 -3
  184. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
  185. package/dist/tools/URLFetcherTool/URLFetcherTool.js +2 -2
  186. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
  187. package/dist/tools/URLFetcherTool/cache.js +6 -3
  188. package/dist/tools/URLFetcherTool/cache.js.map +2 -2
  189. package/dist/tools/URLFetcherTool/htmlToMarkdown.js +3 -1
  190. package/dist/tools/URLFetcherTool/htmlToMarkdown.js.map +2 -2
  191. package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
  192. package/dist/tools/WebSearchTool/prompt.js.map +2 -2
  193. package/dist/tools/WebSearchTool/searchProviders.js +15 -6
  194. package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
  195. package/dist/tools.js +4 -1
  196. package/dist/tools.js.map +2 -2
  197. package/dist/types/core.js +1 -0
  198. package/dist/types/core.js.map +7 -0
  199. package/dist/types/hooks.js +1 -4
  200. package/dist/types/hooks.js.map +2 -2
  201. package/dist/types/marketplace.js +8 -2
  202. package/dist/types/marketplace.js.map +2 -2
  203. package/dist/types/plugin.js +9 -6
  204. package/dist/types/plugin.js.map +2 -2
  205. package/dist/utils/BackgroundShellManager.js +76 -10
  206. package/dist/utils/BackgroundShellManager.js.map +2 -2
  207. package/dist/utils/PersistentShell.js +7 -2
  208. package/dist/utils/PersistentShell.js.map +2 -2
  209. package/dist/utils/advancedFuzzyMatcher.js +4 -1
  210. package/dist/utils/advancedFuzzyMatcher.js.map +2 -2
  211. package/dist/utils/agentLoader.js +69 -35
  212. package/dist/utils/agentLoader.js.map +2 -2
  213. package/dist/utils/agentStorage.js.map +2 -2
  214. package/dist/utils/async.js +163 -0
  215. package/dist/utils/async.js.map +7 -0
  216. package/dist/utils/autoUpdater.js +8 -2
  217. package/dist/utils/autoUpdater.js.map +2 -2
  218. package/dist/utils/commands.js +23 -11
  219. package/dist/utils/commands.js.map +2 -2
  220. package/dist/utils/commonUnixCommands.js +3 -1
  221. package/dist/utils/commonUnixCommands.js.map +2 -2
  222. package/dist/utils/compressionMode.js.map +2 -2
  223. package/dist/utils/config.js +30 -14
  224. package/dist/utils/config.js.map +2 -2
  225. package/dist/utils/debugLogger.js.map +2 -2
  226. package/dist/utils/env.js.map +2 -2
  227. package/dist/utils/envConfig.js +82 -0
  228. package/dist/utils/envConfig.js.map +7 -0
  229. package/dist/utils/errorHandling.js +89 -0
  230. package/dist/utils/errorHandling.js.map +7 -0
  231. package/dist/utils/expertChatStorage.js.map +2 -2
  232. package/dist/utils/fuzzyMatcher.js +13 -7
  233. package/dist/utils/fuzzyMatcher.js.map +2 -2
  234. package/dist/utils/hookManager.js +14 -4
  235. package/dist/utils/hookManager.js.map +2 -2
  236. package/dist/utils/log.js.map +2 -2
  237. package/dist/utils/marketplaceManager.js +44 -9
  238. package/dist/utils/marketplaceManager.js.map +2 -2
  239. package/dist/utils/messageContextManager.js.map +1 -1
  240. package/dist/utils/messages.js +6 -3
  241. package/dist/utils/messages.js.map +2 -2
  242. package/dist/utils/model.js +3 -1
  243. package/dist/utils/model.js.map +2 -2
  244. package/dist/utils/pluginInstaller.js +3 -15
  245. package/dist/utils/pluginInstaller.js.map +2 -2
  246. package/dist/utils/pluginLoader.js +41 -13
  247. package/dist/utils/pluginLoader.js.map +2 -2
  248. package/dist/utils/pluginRegistry.js.map +2 -2
  249. package/dist/utils/pluginValidator.js +71 -49
  250. package/dist/utils/pluginValidator.js.map +2 -2
  251. package/dist/utils/ptyCompat.js.map +2 -2
  252. package/dist/utils/roundConverter.js.map +2 -2
  253. package/dist/utils/secureFile.js +43 -14
  254. package/dist/utils/secureFile.js.map +2 -2
  255. package/dist/utils/sessionState.js.map +2 -2
  256. package/dist/utils/skillLoader.js.map +2 -2
  257. package/dist/utils/teamConfig.js +7 -4
  258. package/dist/utils/teamConfig.js.map +2 -2
  259. package/dist/utils/theme.js.map +2 -2
  260. package/dist/utils/thinking.js.map +2 -2
  261. package/dist/utils/unaryLogging.js.map +2 -2
  262. package/dist/version.js +2 -2
  263. package/dist/version.js.map +1 -1
  264. package/package.json +5 -5
@@ -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 { 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 { getCurrentProjectConfig, saveCurrentProjectConfig } 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}> = ({ onNavigate, onExit }) => {\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 useInput((input, key) => {\n if (key.escape) onExit()\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 dimColor>\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}> = ({ onNavigate, onBack }) => {\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((serverName: string) => {\n onNavigate({ screen: 'server-details', serverName })\n }, [onNavigate])\n\n useInput((input, key) => {\n if (key.escape) onBack()\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 dimColor>\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 = server.status === 'connected' ? theme.success : theme.error\n return {\n label: (\n <Text>\n <Text color={statusColor}>{statusIcon}</Text> {server.name}{' '}\n <Text dimColor>({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\n options={options}\n onChange={handleServerSelect}\n />\n\n <Box marginTop={1}>\n <Text dimColor>\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}> = ({ serverName, onBack, onRefresh }) => {\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 useInput((input, key) => {\n if (key.escape) onBack()\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 dimColor>{server.config.scope}</Text>\n </Text>\n <Text>\n Type: <Text dimColor>{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 dimColor>\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 * 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 { 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}> = ({ onNavigate, onExit }) => {\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 useInput((input, key) => {\n if (key.escape) onExit()\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 dimColor>\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}> = ({ onNavigate, onBack }) => {\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 useInput((input, key) => {\n if (key.escape) onBack()\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 dimColor>\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 dimColor>({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 dimColor>\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}> = ({ serverName, onBack, onRefresh }) => {\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 useInput((input, key) => {\n if (key.escape) onBack()\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 dimColor>{server.config.scope}</Text>\n </Text>\n <Text>\n Type: <Text dimColor>{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 dimColor>\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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",
6
6
  "names": []
7
7
  }
@@ -1,41 +1,103 @@
1
- import React from "react";
1
+ import React, { useState } from "react";
2
+ import { Box, Text, useInput } from "ink";
2
3
  import { ModelConfig } from "../components/ModelConfig.js";
3
4
  import { enableConfigs } from "../utils/config.js";
4
5
  import { triggerModelConfigChange } from "../messages.js";
5
- const help = "Change your AI provider and model settings";
6
- const description = "Change your AI provider and model settings";
7
- const isEnabled = true;
8
- const isHidden = false;
9
- const name = "model";
10
- const type = "local-jsx";
11
- function userFacingName() {
12
- return name;
13
- }
14
- async function call(onDone, context) {
15
- const { abortController } = context;
16
- enableConfigs();
17
- abortController?.abort?.();
18
- return /* @__PURE__ */ React.createElement(
19
- ModelConfig,
20
- {
21
- onClose: () => {
22
- import("../utils/model.js").then(({ reloadModelManager }) => {
23
- reloadModelManager();
24
- triggerModelConfigChange();
25
- onDone();
26
- });
6
+ import { getModelManager } from "../utils/model.js";
7
+ import { getTheme } from "../utils/theme.js";
8
+ import { useExitOnCtrlCD } from "../hooks/useExitOnCtrlCD.js";
9
+ function ModelCommand({ onClose, abortController }) {
10
+ const [mode, setMode] = useState("status");
11
+ const theme = getTheme();
12
+ const exitState = useExitOnCtrlCD(onClose);
13
+ useInput((input, key) => {
14
+ if (mode === "status") {
15
+ if (key.return || input === "c" || input === "C") {
16
+ enableConfigs();
17
+ abortController?.abort?.();
18
+ setMode("config");
19
+ } else if (key.escape) {
20
+ onClose();
27
21
  }
28
22
  }
29
- );
23
+ });
24
+ if (mode === "config") {
25
+ return /* @__PURE__ */ React.createElement(
26
+ ModelConfig,
27
+ {
28
+ onClose: () => {
29
+ import("../utils/model.js").then(({ reloadModelManager }) => {
30
+ reloadModelManager();
31
+ triggerModelConfigChange();
32
+ setMode("status");
33
+ });
34
+ }
35
+ }
36
+ );
37
+ }
38
+ try {
39
+ const modelManager = getModelManager();
40
+ const pointers = ["main", "task", "reasoning", "quick"];
41
+ return /* @__PURE__ */ React.createElement(
42
+ Box,
43
+ {
44
+ flexDirection: "column",
45
+ borderStyle: "round",
46
+ borderColor: theme.secondaryBorder,
47
+ paddingX: 2,
48
+ paddingY: 1
49
+ },
50
+ /* @__PURE__ */ React.createElement(Text, { bold: true }, "\u{1F4CA} Model Status", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
51
+ /* @__PURE__ */ React.createElement(Text, null, " "),
52
+ pointers.map((pointer) => {
53
+ try {
54
+ const model2 = modelManager.getModel(pointer);
55
+ if (model2 && model2.name && model2.provider) {
56
+ return /* @__PURE__ */ React.createElement(Box, { key: pointer }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, pointer.toUpperCase().padEnd(10)), " ", "\u2192 ", model2.name, " ", /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "(", model2.provider, ", ", model2.modelName || "unknown", ")")));
57
+ } else {
58
+ return /* @__PURE__ */ React.createElement(Box, { key: pointer }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, pointer.toUpperCase().padEnd(10)), " ", "\u2192 ", /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Not configured")));
59
+ }
60
+ } catch {
61
+ return /* @__PURE__ */ React.createElement(Box, { key: pointer }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.minto }, pointer.toUpperCase().padEnd(10)), " ", "\u2192 ", /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Error")));
62
+ }
63
+ }),
64
+ /* @__PURE__ */ React.createElement(Text, null, " "),
65
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Enter"), " or ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "C"), " to configure models"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Esc"), " to close"))
66
+ );
67
+ } catch (error) {
68
+ return /* @__PURE__ */ React.createElement(
69
+ Box,
70
+ {
71
+ flexDirection: "column",
72
+ borderStyle: "round",
73
+ borderColor: theme.error,
74
+ paddingX: 2,
75
+ paddingY: 1
76
+ },
77
+ /* @__PURE__ */ React.createElement(Text, { bold: true }, "\u{1F4CA} Model Status Error"),
78
+ /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Error reading model status: ", String(error)),
79
+ /* @__PURE__ */ React.createElement(Text, null, " "),
80
+ /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Enter"), " to configure models")
81
+ );
82
+ }
30
83
  }
84
+ const model = {
85
+ name: "model",
86
+ description: "View model status and configure AI provider settings",
87
+ aliases: ["ms", "modelstatus", "model-status"],
88
+ isEnabled: true,
89
+ isHidden: false,
90
+ type: "local-jsx",
91
+ userFacingName() {
92
+ return "model";
93
+ },
94
+ async call(onDone, context) {
95
+ const { abortController } = context || {};
96
+ return /* @__PURE__ */ React.createElement(ModelCommand, { onClose: onDone, abortController });
97
+ }
98
+ };
99
+ var model_default = model;
31
100
  export {
32
- call,
33
- description,
34
- help,
35
- isEnabled,
36
- isHidden,
37
- name,
38
- type,
39
- userFacingName
101
+ model_default as default
40
102
  };
41
103
  //# sourceMappingURL=model.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/model.tsx"],
4
- "sourcesContent": ["import React from 'react'\nimport { render } from 'ink'\nimport { ModelConfig } from '@components/ModelConfig'\nimport { enableConfigs } from '@utils/config'\nimport { triggerModelConfigChange } from '@messages'\n\nexport const help = 'Change your AI provider and model settings'\nexport const description = 'Change your AI provider and model settings'\nexport const isEnabled = true\nexport const isHidden = false\nexport const name = 'model'\nexport const type = 'local-jsx'\n\nexport function userFacingName(): string {\n return name\n}\n\nexport async function call(\n onDone: (result?: string) => void,\n context: any,\n): Promise<React.ReactNode> {\n const { abortController } = context\n enableConfigs()\n abortController?.abort?.()\n return (\n <ModelConfig\n onClose={() => {\n // Force ModelManager reload to ensure UI sync - wait for completion before closing\n import('@utils/model').then(({ reloadModelManager }) => {\n reloadModelManager()\n // \uD83D\uDD27 Critical fix: Trigger global UI refresh after model config changes\n // This ensures PromptInput component detects ModelManager singleton state changes\n triggerModelConfigChange()\n // Only close after reload is complete to ensure UI synchronization\n onDone()\n })\n }}\n />\n )\n}\n"],
5
- "mappings": "AAAA,OAAO,WAAW;AAElB,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,gCAAgC;AAElC,MAAM,OAAO;AACb,MAAM,cAAc;AACpB,MAAM,YAAY;AAClB,MAAM,WAAW;AACjB,MAAM,OAAO;AACb,MAAM,OAAO;AAEb,SAAS,iBAAyB;AACvC,SAAO;AACT;AAEA,eAAsB,KACpB,QACA,SAC0B;AAC1B,QAAM,EAAE,gBAAgB,IAAI;AAC5B,gBAAc;AACd,mBAAiB,QAAQ;AACzB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,MAAM;AAEb,eAAO,cAAc,EAAE,KAAK,CAAC,EAAE,mBAAmB,MAAM;AACtD,6BAAmB;AAGnB,mCAAyB;AAEzB,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;",
6
- "names": []
4
+ "sourcesContent": ["import React, { useState } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { ModelConfig } from '@components/ModelConfig'\nimport { enableConfigs } from '@utils/config'\nimport { triggerModelConfigChange } from '@messages'\nimport { getModelManager } from '@utils/model'\nimport { getTheme } from '@utils/theme'\nimport { useExitOnCtrlCD } from '@hooks/useExitOnCtrlCD'\nimport type { Command } from '@commands'\n\ntype Props = {\n onClose: () => void\n abortController?: AbortController\n}\n\n/**\n * Combined Model Command - Shows status and provides configuration\n *\n * This merges the functionality of /model and /modelstatus into a single command.\n * First shows current model status, then allows entering configuration mode.\n */\nfunction ModelCommand({ onClose, abortController }: Props): React.ReactNode {\n const [mode, setMode] = useState<'status' | 'config'>('status')\n const theme = getTheme()\n const exitState = useExitOnCtrlCD(onClose)\n\n useInput((input, key) => {\n if (mode === 'status') {\n if (key.return || input === 'c' || input === 'C') {\n enableConfigs()\n abortController?.abort?.()\n setMode('config')\n } else if (key.escape) {\n onClose()\n }\n }\n })\n\n if (mode === 'config') {\n return (\n <ModelConfig\n onClose={() => {\n import('@utils/model').then(({ reloadModelManager }) => {\n reloadModelManager()\n triggerModelConfigChange()\n // Return to status mode instead of exiting completely\n setMode('status')\n })\n }}\n />\n )\n }\n\n // Status mode - show current model configuration\n try {\n const modelManager = getModelManager()\n const pointers = ['main', 'task', 'reasoning', 'quick'] as const\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.secondaryBorder}\n paddingX={2}\n paddingY={1}\n >\n <Text bold>\n \uD83D\uDCCA Model Status{' '}\n {exitState.pending\n ? `(press ${exitState.keyName} again to exit)`\n : ''}\n </Text>\n <Text> </Text>\n\n {pointers.map(pointer => {\n try {\n const model = modelManager.getModel(pointer)\n if (model && model.name && model.provider) {\n return (\n <Box key={pointer}>\n <Text>\n <Text bold color={theme.minto}>\n {pointer.toUpperCase().padEnd(10)}\n </Text>{' '}\n \u2192 {model.name}{' '}\n <Text color={theme.secondaryText}>\n ({model.provider}, {model.modelName || 'unknown'})\n </Text>\n </Text>\n </Box>\n )\n } else {\n return (\n <Box key={pointer}>\n <Text>\n <Text bold color={theme.minto}>\n {pointer.toUpperCase().padEnd(10)}\n </Text>{' '}\n \u2192 <Text color={theme.error}>Not configured</Text>\n </Text>\n </Box>\n )\n }\n } catch {\n return (\n <Box key={pointer}>\n <Text>\n <Text bold color={theme.minto}>\n {pointer.toUpperCase().padEnd(10)}\n </Text>{' '}\n \u2192 <Text color={theme.error}>Error</Text>\n </Text>\n </Box>\n )\n }\n })}\n\n <Text> </Text>\n <Box flexDirection=\"column\">\n <Text dimColor>\n Press <Text bold>Enter</Text> or <Text bold>C</Text> to configure\n models\n </Text>\n <Text dimColor>\n Press <Text bold>Esc</Text> to close\n </Text>\n </Box>\n </Box>\n )\n } catch (error) {\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.error}\n paddingX={2}\n paddingY={1}\n >\n <Text bold>\uD83D\uDCCA Model Status Error</Text>\n <Text color={theme.error}>\n Error reading model status: {String(error)}\n </Text>\n <Text> </Text>\n <Text dimColor>\n Press <Text bold>Enter</Text> to configure models\n </Text>\n </Box>\n )\n }\n}\n\nconst model: Command = {\n name: 'model',\n description: 'View model status and configure AI provider settings',\n aliases: ['ms', 'modelstatus', 'model-status'],\n isEnabled: true,\n isHidden: false,\n type: 'local-jsx',\n userFacingName() {\n return 'model'\n },\n async call(onDone, context) {\n const { abortController } = context || {}\n return <ModelCommand onClose={onDone} abortController={abortController} />\n },\n}\n\nexport default model\n"],
5
+ "mappings": "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",
6
+ "names": ["model"]
7
7
  }
@@ -28,33 +28,61 @@ const AddMarketplaceForm = ({
28
28
  if (err instanceof MarketplaceError) {
29
29
  setError(err.message);
30
30
  } else {
31
- setError(err instanceof Error ? err.message : "Failed to add marketplace");
31
+ setError(
32
+ err instanceof Error ? err.message : "Failed to add marketplace"
33
+ );
32
34
  }
33
35
  } finally {
34
36
  setAdding(false);
35
37
  }
36
38
  };
37
- useInput((input, key) => {
38
- if (key.escape && !adding) {
39
- onBack();
40
- } else if (key.return && !adding) {
41
- handleSubmit();
42
- }
43
- }, { isActive: !adding });
44
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.primary, padding: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, "Add Marketplace"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, "Enter marketplace source:"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Examples:"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2022 owner/repo (GitHub shorthand)"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2022 git@github.com:owner/repo.git (SSH URL)"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2022 https://github.com/owner/repo.git (HTTPS URL)"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2022 ./path/to/local/marketplace (Local path)"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "Source: "), /* @__PURE__ */ React.createElement(
45
- TextInput,
39
+ useInput(
40
+ (input, key) => {
41
+ if (key.escape && !adding) {
42
+ onBack();
43
+ } else if (key.return && !adding) {
44
+ handleSubmit();
45
+ }
46
+ },
47
+ { isActive: !adding }
48
+ );
49
+ return /* @__PURE__ */ React.createElement(
50
+ Box,
46
51
  {
47
- value: source,
48
- onChange: setSource,
49
- placeholder: "Enter source...",
50
- focus: !adding,
51
- showCursor: !adding,
52
- isDimmed: adding,
53
- columns: 60,
54
- cursorOffset,
55
- onChangeCursorOffset: setCursorOffset
56
- }
57
- ))), error && /* @__PURE__ */ React.createElement(Box, { marginTop: 1, borderStyle: "round", borderColor: theme.error, padding: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "\u2717 ", error)), adding && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(SimpleSpinner, null), /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, " Adding marketplace...")), !adding && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "Enter"), " to add \xB7 ", /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Esc"), " to cancel")));
52
+ flexDirection: "column",
53
+ borderStyle: "round",
54
+ borderColor: theme.primary,
55
+ padding: 1
56
+ },
57
+ /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, "Add Marketplace"),
58
+ /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, "Enter marketplace source:"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Examples:"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2022 owner/repo (GitHub shorthand)"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2022 git@github.com:owner/repo.git (SSH URL)"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2022 https://github.com/owner/repo.git (HTTPS URL)"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2022 ./path/to/local/marketplace (Local path)"))),
59
+ /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "Source: "), /* @__PURE__ */ React.createElement(
60
+ TextInput,
61
+ {
62
+ value: source,
63
+ onChange: setSource,
64
+ placeholder: "Enter source...",
65
+ focus: !adding,
66
+ showCursor: !adding,
67
+ isDimmed: adding,
68
+ columns: 60,
69
+ cursorOffset,
70
+ onChangeCursorOffset: setCursorOffset
71
+ }
72
+ ))),
73
+ error && /* @__PURE__ */ React.createElement(
74
+ Box,
75
+ {
76
+ marginTop: 1,
77
+ borderStyle: "round",
78
+ borderColor: theme.error,
79
+ padding: 1
80
+ },
81
+ /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "\u2717 ", error)
82
+ ),
83
+ adding && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(SimpleSpinner, null), /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, " Adding marketplace...")),
84
+ !adding && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "Enter"), " to add \xB7", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Esc"), " to cancel"))
85
+ );
58
86
  };
59
87
  export {
60
88
  AddMarketplaceForm
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/commands/plugin/AddMarketplaceForm.tsx"],
4
- "sourcesContent": ["/**\n * AddMarketplaceForm Component\n *\n * Interactive form for adding new plugin marketplaces\n */\n\nimport React, { useState } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { SimpleSpinner } from '@components/Spinner'\nimport TextInput from '@components/TextInput'\nimport { addMarketplace } from '@utils/marketplaceManager'\nimport { MarketplaceError } from '../../types/marketplace'\nimport { getTheme } from '@utils/theme'\n\nexport interface NavigationProps {\n onNavigate: (params: { screen: string; [key: string]: any }) => void\n onBack: () => void\n}\n\nexport const AddMarketplaceForm: React.FC<NavigationProps> = ({\n onNavigate,\n onBack\n}) => {\n const [source, setSource] = useState('')\n const [adding, setAdding] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [cursorOffset, setCursorOffset] = useState(0)\n const theme = getTheme()\n\n const handleSubmit = async () => {\n if (!source.trim()) {\n setError('Source cannot be empty')\n return\n }\n\n setAdding(true)\n setError(null)\n\n try {\n const marketplace = await addMarketplace(source)\n // Success - navigate back to marketplace manager\n onBack()\n } catch (err) {\n if (err instanceof MarketplaceError) {\n setError(err.message)\n } else {\n setError(err instanceof Error ? err.message : 'Failed to add marketplace')\n }\n } finally {\n setAdding(false)\n }\n }\n\n useInput((input, key) => {\n if (key.escape && !adding) {\n onBack()\n } else if (key.return && !adding) {\n handleSubmit()\n }\n }, { isActive: !adding })\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.primary} padding={1}>\n <Text bold color={theme.primary}>Add Marketplace</Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>Enter marketplace source:</Text>\n <Box marginTop={1} flexDirection=\"column\" marginLeft={2}>\n <Text dimColor>Examples:</Text>\n <Text dimColor> \u2022 owner/repo (GitHub shorthand)</Text>\n <Text dimColor> \u2022 git@github.com:owner/repo.git (SSH URL)</Text>\n <Text dimColor> \u2022 https://github.com/owner/repo.git (HTTPS URL)</Text>\n <Text dimColor> \u2022 ./path/to/local/marketplace (Local path)</Text>\n </Box>\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Box>\n <Text color={theme.success}>Source: </Text>\n <TextInput\n value={source}\n onChange={setSource}\n placeholder=\"Enter source...\"\n focus={!adding}\n showCursor={!adding}\n isDimmed={adding}\n columns={60}\n cursorOffset={cursorOffset}\n onChangeCursorOffset={setCursorOffset}\n />\n </Box>\n </Box>\n\n {error && (\n <Box marginTop={1} borderStyle=\"round\" borderColor={theme.error} padding={1}>\n <Text color={theme.error}>\u2717 {error}</Text>\n </Box>\n )}\n\n {adding && (\n <Box marginTop={1}>\n <SimpleSpinner />\n <Text color={theme.primary}> Adding marketplace...</Text>\n </Box>\n )}\n\n {!adding && (\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={theme.success}>Enter</Text> to add \u00B7 <Text color={theme.error}>Esc</Text> to cancel\n </Text>\n </Box>\n )}\n </Box>\n )\n}\n"],
5
- "mappings": "AAMA,OAAO,SAAS,gBAAgB;AAChC,SAAS,KAAK,MAAM,gBAAgB;AACpC,SAAS,qBAAqB;AAC9B,OAAO,eAAe;AACtB,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,gBAAgB;AAOlB,MAAM,qBAAgD,CAAC;AAAA,EAC5D;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,EAAE;AACvC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,CAAC;AAClD,QAAM,QAAQ,SAAS;AAEvB,QAAM,eAAe,YAAY;AAC/B,QAAI,CAAC,OAAO,KAAK,GAAG;AAClB,eAAS,wBAAwB;AACjC;AAAA,IACF;AAEA,cAAU,IAAI;AACd,aAAS,IAAI;AAEb,QAAI;AACF,YAAM,cAAc,MAAM,eAAe,MAAM;AAE/C,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,eAAe,kBAAkB;AACnC,iBAAS,IAAI,OAAO;AAAA,MACtB,OAAO;AACL,iBAAS,eAAe,QAAQ,IAAI,UAAU,2BAA2B;AAAA,MAC3E;AAAA,IACF,UAAE;AACA,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAEA,WAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,IAAI,UAAU,CAAC,QAAQ;AACzB,aAAO;AAAA,IACT,WAAW,IAAI,UAAU,CAAC,QAAQ;AAChC,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC;AAExB,SACE,oCAAC,OAAI,eAAc,UAAS,aAAY,SAAQ,aAAa,MAAM,SAAS,SAAS,KACnF,oCAAC,QAAK,MAAI,MAAC,OAAO,MAAM,WAAS,iBAAe,GAEhD,oCAAC,OAAI,WAAW,GAAG,eAAc,YAC/B,oCAAC,YAAK,2BAAyB,GAC/B,oCAAC,OAAI,WAAW,GAAG,eAAc,UAAS,YAAY,KACpD,oCAAC,QAAK,UAAQ,QAAC,WAAS,GACxB,oCAAC,QAAK,UAAQ,QAAC,uCAAgC,GAC/C,oCAAC,QAAK,UAAQ,QAAC,iDAA0C,GACzD,oCAAC,QAAK,UAAQ,QAAC,uDAAgD,GAC/D,oCAAC,QAAK,UAAQ,QAAC,kDAA2C,CAC5D,CACF,GAEA,oCAAC,OAAI,WAAW,GAAG,eAAc,YAC/B,oCAAC,WACC,oCAAC,QAAK,OAAO,MAAM,WAAS,UAAQ,GACpC;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP,UAAU;AAAA,MACV,aAAY;AAAA,MACZ,OAAO,CAAC;AAAA,MACR,YAAY,CAAC;AAAA,MACb,UAAU;AAAA,MACV,SAAS;AAAA,MACT;AAAA,MACA,sBAAsB;AAAA;AAAA,EACxB,CACF,CACF,GAEC,SACC,oCAAC,OAAI,WAAW,GAAG,aAAY,SAAQ,aAAa,MAAM,OAAO,SAAS,KACxE,oCAAC,QAAK,OAAO,MAAM,SAAO,WAAG,KAAM,CACrC,GAGD,UACC,oCAAC,OAAI,WAAW,KACd,oCAAC,mBAAc,GACf,oCAAC,QAAK,OAAO,MAAM,WAAS,wBAAsB,CACpD,GAGD,CAAC,UACA,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,UAAQ,QACZ,oCAAC,QAAK,OAAO,MAAM,WAAS,OAAK,GAAO,iBAAU,oCAAC,QAAK,OAAO,MAAM,SAAO,KAAG,GAAO,YACxF,CACF,CAEJ;AAEJ;",
4
+ "sourcesContent": ["/**\n * AddMarketplaceForm Component\n *\n * Interactive form for adding new plugin marketplaces\n */\n\nimport React, { useState } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { SimpleSpinner } from '@components/Spinner'\nimport TextInput from '@components/TextInput'\nimport { addMarketplace } from '@utils/marketplaceManager'\nimport { MarketplaceError } from '../../types/marketplace'\nimport { getTheme } from '@utils/theme'\n\nexport interface NavigationProps {\n onNavigate: (params: { screen: string; [key: string]: any }) => void\n onBack: () => void\n}\n\nexport const AddMarketplaceForm: React.FC<NavigationProps> = ({\n onNavigate,\n onBack,\n}) => {\n const [source, setSource] = useState('')\n const [adding, setAdding] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [cursorOffset, setCursorOffset] = useState(0)\n const theme = getTheme()\n\n const handleSubmit = async () => {\n if (!source.trim()) {\n setError('Source cannot be empty')\n return\n }\n\n setAdding(true)\n setError(null)\n\n try {\n const marketplace = await addMarketplace(source)\n // Success - navigate back to marketplace manager\n onBack()\n } catch (err) {\n if (err instanceof MarketplaceError) {\n setError(err.message)\n } else {\n setError(\n err instanceof Error ? err.message : 'Failed to add marketplace',\n )\n }\n } finally {\n setAdding(false)\n }\n }\n\n useInput(\n (input, key) => {\n if (key.escape && !adding) {\n onBack()\n } else if (key.return && !adding) {\n handleSubmit()\n }\n },\n { isActive: !adding },\n )\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.primary}\n padding={1}\n >\n <Text bold color={theme.primary}>\n Add Marketplace\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>Enter marketplace source:</Text>\n <Box marginTop={1} flexDirection=\"column\" marginLeft={2}>\n <Text dimColor>Examples:</Text>\n <Text dimColor> \u2022 owner/repo (GitHub shorthand)</Text>\n <Text dimColor> \u2022 git@github.com:owner/repo.git (SSH URL)</Text>\n <Text dimColor> \u2022 https://github.com/owner/repo.git (HTTPS URL)</Text>\n <Text dimColor> \u2022 ./path/to/local/marketplace (Local path)</Text>\n </Box>\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Box>\n <Text color={theme.success}>Source: </Text>\n <TextInput\n value={source}\n onChange={setSource}\n placeholder=\"Enter source...\"\n focus={!adding}\n showCursor={!adding}\n isDimmed={adding}\n columns={60}\n cursorOffset={cursorOffset}\n onChangeCursorOffset={setCursorOffset}\n />\n </Box>\n </Box>\n\n {error && (\n <Box\n marginTop={1}\n borderStyle=\"round\"\n borderColor={theme.error}\n padding={1}\n >\n <Text color={theme.error}>\u2717 {error}</Text>\n </Box>\n )}\n\n {adding && (\n <Box marginTop={1}>\n <SimpleSpinner />\n <Text color={theme.primary}> Adding marketplace...</Text>\n </Box>\n )}\n\n {!adding && (\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={theme.success}>Enter</Text> to add \u00B7{' '}\n <Text color={theme.error}>Esc</Text> to cancel\n </Text>\n </Box>\n )}\n </Box>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -31,39 +31,51 @@ const ConfirmDialog = ({
31
31
  onCancel();
32
32
  }
33
33
  });
34
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.warning, padding: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.warning }, title), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, message.split("\n").map((line, idx) => {
35
- return /* @__PURE__ */ React.createElement(Text, { ...{ key: `line-${idx}` } }, line);
36
- })), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, gap: 2 }, /* @__PURE__ */ React.createElement(
34
+ return /* @__PURE__ */ React.createElement(
37
35
  Box,
38
36
  {
39
- borderStyle: focused === "confirm" ? "round" : "single",
40
- borderColor: focused === "confirm" ? confirmColor || theme.success : theme.secondaryText,
41
- paddingX: 2
37
+ flexDirection: "column",
38
+ borderStyle: "round",
39
+ borderColor: theme.warning,
40
+ padding: 1
42
41
  },
43
- /* @__PURE__ */ React.createElement(
44
- Text,
42
+ /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.warning }, title),
43
+ /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, message.split("\n").map((line, idx) => {
44
+ return /* @__PURE__ */ React.createElement(Text, { ...{ key: `line-${idx}` } }, line);
45
+ })),
46
+ /* @__PURE__ */ React.createElement(Box, { marginTop: 1, gap: 2 }, /* @__PURE__ */ React.createElement(
47
+ Box,
45
48
  {
46
- color: focused === "confirm" ? confirmColor || theme.success : theme.secondaryText,
47
- bold: focused === "confirm"
49
+ borderStyle: focused === "confirm" ? "round" : "single",
50
+ borderColor: focused === "confirm" ? confirmColor || theme.success : theme.secondaryText,
51
+ paddingX: 2
48
52
  },
49
- confirmText
50
- )
51
- ), /* @__PURE__ */ React.createElement(
52
- Box,
53
- {
54
- borderStyle: focused === "cancel" ? "round" : "single",
55
- borderColor: focused === "cancel" ? theme.primary : theme.secondaryText,
56
- paddingX: 2
57
- },
58
- /* @__PURE__ */ React.createElement(
59
- Text,
53
+ /* @__PURE__ */ React.createElement(
54
+ Text,
55
+ {
56
+ color: focused === "confirm" ? confirmColor || theme.success : theme.secondaryText,
57
+ bold: focused === "confirm"
58
+ },
59
+ confirmText
60
+ )
61
+ ), /* @__PURE__ */ React.createElement(
62
+ Box,
60
63
  {
61
- color: focused === "cancel" ? theme.primary : theme.secondaryText,
62
- bold: focused === "cancel"
64
+ borderStyle: focused === "cancel" ? "round" : "single",
65
+ borderColor: focused === "cancel" ? theme.primary : theme.secondaryText,
66
+ paddingX: 2
63
67
  },
64
- cancelText
65
- )
66
- )), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u2190 \u2192 navigate \xB7 ", /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "Enter"), " confirm \xB7 ", /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Esc"), " cancel")));
68
+ /* @__PURE__ */ React.createElement(
69
+ Text,
70
+ {
71
+ color: focused === "cancel" ? theme.primary : theme.secondaryText,
72
+ bold: focused === "cancel"
73
+ },
74
+ cancelText
75
+ )
76
+ )),
77
+ /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u2190 \u2192 navigate \xB7 ", /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "Enter"), " confirm \xB7", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Esc"), " cancel"))
78
+ );
67
79
  };
68
80
  export {
69
81
  ConfirmDialog
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/commands/plugin/ConfirmDialog.tsx"],
4
- "sourcesContent": ["/**\n * ConfirmDialog Component\n *\n * Reusable confirmation dialog for marketplace operations\n */\n\nimport React from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { getTheme } from '@utils/theme'\n\nexport interface ConfirmDialogProps {\n title: string\n message: string\n onConfirm: () => void\n onCancel: () => void\n confirmColor?: string\n confirmText?: string\n cancelText?: string\n}\n\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = ({\n title,\n message,\n onConfirm,\n onCancel,\n confirmColor,\n confirmText = 'Yes',\n cancelText = 'No'\n}) => {\n const theme = getTheme()\n const [focused, setFocused] = React.useState<'confirm' | 'cancel'>('cancel')\n\n useInput((input, key) => {\n if (key.escape) {\n onCancel()\n } else if (key.return) {\n if (focused === 'confirm') {\n onConfirm()\n } else {\n onCancel()\n }\n } else if (key.leftArrow) {\n setFocused(focused === 'confirm' ? 'cancel' : 'confirm')\n } else if (key.rightArrow) {\n setFocused(focused === 'confirm' ? 'cancel' : 'confirm')\n } else if (input === 'y' || input === 'Y') {\n onConfirm()\n } else if (input === 'n' || input === 'N') {\n onCancel()\n }\n })\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.warning} padding={1}>\n <Text bold color={theme.warning}>{title}</Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {message.split('\\n').map((line, idx) => {\n // Handle React Text component which doesn't accept key prop in its type definition\n // but we need unique keys for list rendering\n return <Text {...{ key: `line-${idx}` } as any}>{line}</Text>\n })}\n </Box>\n\n <Box marginTop={1} gap={2}>\n <Box\n borderStyle={focused === 'confirm' ? 'round' : 'single'}\n borderColor={focused === 'confirm' ? (confirmColor || theme.success) : theme.secondaryText}\n paddingX={2}\n >\n <Text\n color={focused === 'confirm' ? (confirmColor || theme.success) : theme.secondaryText}\n bold={focused === 'confirm'}\n >\n {confirmText}\n </Text>\n </Box>\n\n <Box\n borderStyle={focused === 'cancel' ? 'round' : 'single'}\n borderColor={focused === 'cancel' ? theme.primary : theme.secondaryText}\n paddingX={2}\n >\n <Text\n color={focused === 'cancel' ? theme.primary : theme.secondaryText}\n bold={focused === 'cancel'}\n >\n {cancelText}\n </Text>\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n \u2190 \u2192 navigate \u00B7 <Text color={theme.success}>Enter</Text> confirm \u00B7 <Text color={theme.error}>Esc</Text> cancel\n </Text>\n </Box>\n </Box>\n )\n}\n"],
5
- "mappings": "AAMA,OAAO,WAAW;AAClB,SAAS,KAAK,MAAM,gBAAgB;AACpC,SAAS,gBAAgB;AAYlB,MAAM,gBAA8C,CAAC;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,aAAa;AACf,MAAM;AACJ,QAAM,QAAQ,SAAS;AACvB,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAA+B,QAAQ;AAE3E,WAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,IAAI,QAAQ;AACd,eAAS;AAAA,IACX,WAAW,IAAI,QAAQ;AACrB,UAAI,YAAY,WAAW;AACzB,kBAAU;AAAA,MACZ,OAAO;AACL,iBAAS;AAAA,MACX;AAAA,IACF,WAAW,IAAI,WAAW;AACxB,iBAAW,YAAY,YAAY,WAAW,SAAS;AAAA,IACzD,WAAW,IAAI,YAAY;AACzB,iBAAW,YAAY,YAAY,WAAW,SAAS;AAAA,IACzD,WAAW,UAAU,OAAO,UAAU,KAAK;AACzC,gBAAU;AAAA,IACZ,WAAW,UAAU,OAAO,UAAU,KAAK;AACzC,eAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,SACE,oCAAC,OAAI,eAAc,UAAS,aAAY,SAAQ,aAAa,MAAM,SAAS,SAAS,KACnF,oCAAC,QAAK,MAAI,MAAC,OAAO,MAAM,WAAU,KAAM,GAExC,oCAAC,OAAI,WAAW,GAAG,eAAc,YAC9B,QAAQ,MAAM,IAAI,EAAE,IAAI,CAAC,MAAM,QAAQ;AAGtC,WAAO,oCAAC,QAAM,GAAG,EAAE,KAAK,QAAQ,GAAG,GAAG,KAAW,IAAK;AAAA,EACxD,CAAC,CACH,GAEA,oCAAC,OAAI,WAAW,GAAG,KAAK,KACtB;AAAA,IAAC;AAAA;AAAA,MACC,aAAa,YAAY,YAAY,UAAU;AAAA,MAC/C,aAAa,YAAY,YAAa,gBAAgB,MAAM,UAAW,MAAM;AAAA,MAC7E,UAAU;AAAA;AAAA,IAEV;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,YAAY,YAAa,gBAAgB,MAAM,UAAW,MAAM;AAAA,QACvE,MAAM,YAAY;AAAA;AAAA,MAEjB;AAAA,IACH;AAAA,EACF,GAEA;AAAA,IAAC;AAAA;AAAA,MACC,aAAa,YAAY,WAAW,UAAU;AAAA,MAC9C,aAAa,YAAY,WAAW,MAAM,UAAU,MAAM;AAAA,MAC1D,UAAU;AAAA;AAAA,IAEV;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,YAAY,WAAW,MAAM,UAAU,MAAM;AAAA,QACpD,MAAM,YAAY;AAAA;AAAA,MAEjB;AAAA,IACH;AAAA,EACF,CACF,GAEA,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,UAAQ,QAAC,gCACE,oCAAC,QAAK,OAAO,MAAM,WAAS,OAAK,GAAO,kBAAW,oCAAC,QAAK,OAAO,MAAM,SAAO,KAAG,GAAO,SACxG,CACF,CACF;AAEJ;",
4
+ "sourcesContent": ["/**\n * ConfirmDialog Component\n *\n * Reusable confirmation dialog for marketplace operations\n */\n\nimport React from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { getTheme } from '@utils/theme'\n\nexport interface ConfirmDialogProps {\n title: string\n message: string\n onConfirm: () => void\n onCancel: () => void\n confirmColor?: string\n confirmText?: string\n cancelText?: string\n}\n\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = ({\n title,\n message,\n onConfirm,\n onCancel,\n confirmColor,\n confirmText = 'Yes',\n cancelText = 'No',\n}) => {\n const theme = getTheme()\n const [focused, setFocused] = React.useState<'confirm' | 'cancel'>('cancel')\n\n useInput((input, key) => {\n if (key.escape) {\n onCancel()\n } else if (key.return) {\n if (focused === 'confirm') {\n onConfirm()\n } else {\n onCancel()\n }\n } else if (key.leftArrow) {\n setFocused(focused === 'confirm' ? 'cancel' : 'confirm')\n } else if (key.rightArrow) {\n setFocused(focused === 'confirm' ? 'cancel' : 'confirm')\n } else if (input === 'y' || input === 'Y') {\n onConfirm()\n } else if (input === 'n' || input === 'N') {\n onCancel()\n }\n })\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.warning}\n padding={1}\n >\n <Text bold color={theme.warning}>\n {title}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {message.split('\\n').map((line, idx) => {\n // Handle React Text component which doesn't accept key prop in its type definition\n // but we need unique keys for list rendering\n return <Text {...({ key: `line-${idx}` } as any)}>{line}</Text>\n })}\n </Box>\n\n <Box marginTop={1} gap={2}>\n <Box\n borderStyle={focused === 'confirm' ? 'round' : 'single'}\n borderColor={\n focused === 'confirm'\n ? confirmColor || theme.success\n : theme.secondaryText\n }\n paddingX={2}\n >\n <Text\n color={\n focused === 'confirm'\n ? confirmColor || theme.success\n : theme.secondaryText\n }\n bold={focused === 'confirm'}\n >\n {confirmText}\n </Text>\n </Box>\n\n <Box\n borderStyle={focused === 'cancel' ? 'round' : 'single'}\n borderColor={\n focused === 'cancel' ? theme.primary : theme.secondaryText\n }\n paddingX={2}\n >\n <Text\n color={focused === 'cancel' ? theme.primary : theme.secondaryText}\n bold={focused === 'cancel'}\n >\n {cancelText}\n </Text>\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n \u2190 \u2192 navigate \u00B7 <Text color={theme.success}>Enter</Text> confirm \u00B7{' '}\n <Text color={theme.error}>Esc</Text> cancel\n </Text>\n </Box>\n </Box>\n )\n}\n"],
5
+ "mappings": "AAMA,OAAO,WAAW;AAClB,SAAS,KAAK,MAAM,gBAAgB;AACpC,SAAS,gBAAgB;AAYlB,MAAM,gBAA8C,CAAC;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,aAAa;AACf,MAAM;AACJ,QAAM,QAAQ,SAAS;AACvB,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAA+B,QAAQ;AAE3E,WAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,IAAI,QAAQ;AACd,eAAS;AAAA,IACX,WAAW,IAAI,QAAQ;AACrB,UAAI,YAAY,WAAW;AACzB,kBAAU;AAAA,MACZ,OAAO;AACL,iBAAS;AAAA,MACX;AAAA,IACF,WAAW,IAAI,WAAW;AACxB,iBAAW,YAAY,YAAY,WAAW,SAAS;AAAA,IACzD,WAAW,IAAI,YAAY;AACzB,iBAAW,YAAY,YAAY,WAAW,SAAS;AAAA,IACzD,WAAW,UAAU,OAAO,UAAU,KAAK;AACzC,gBAAU;AAAA,IACZ,WAAW,UAAU,OAAO,UAAU,KAAK;AACzC,eAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAc;AAAA,MACd,aAAY;AAAA,MACZ,aAAa,MAAM;AAAA,MACnB,SAAS;AAAA;AAAA,IAET,oCAAC,QAAK,MAAI,MAAC,OAAO,MAAM,WACrB,KACH;AAAA,IAEA,oCAAC,OAAI,WAAW,GAAG,eAAc,YAC9B,QAAQ,MAAM,IAAI,EAAE,IAAI,CAAC,MAAM,QAAQ;AAGtC,aAAO,oCAAC,QAAM,GAAI,EAAE,KAAK,QAAQ,GAAG,GAAG,KAAY,IAAK;AAAA,IAC1D,CAAC,CACH;AAAA,IAEA,oCAAC,OAAI,WAAW,GAAG,KAAK,KACtB;AAAA,MAAC;AAAA;AAAA,QACC,aAAa,YAAY,YAAY,UAAU;AAAA,QAC/C,aACE,YAAY,YACR,gBAAgB,MAAM,UACtB,MAAM;AAAA,QAEZ,UAAU;AAAA;AAAA,MAEV;AAAA,QAAC;AAAA;AAAA,UACC,OACE,YAAY,YACR,gBAAgB,MAAM,UACtB,MAAM;AAAA,UAEZ,MAAM,YAAY;AAAA;AAAA,QAEjB;AAAA,MACH;AAAA,IACF,GAEA;AAAA,MAAC;AAAA;AAAA,QACC,aAAa,YAAY,WAAW,UAAU;AAAA,QAC9C,aACE,YAAY,WAAW,MAAM,UAAU,MAAM;AAAA,QAE/C,UAAU;AAAA;AAAA,MAEV;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,YAAY,WAAW,MAAM,UAAU,MAAM;AAAA,UACpD,MAAM,YAAY;AAAA;AAAA,QAEjB;AAAA,MACH;AAAA,IACF,CACF;AAAA,IAEA,oCAAC,OAAI,WAAW,KACd,oCAAC,QAAK,UAAQ,QAAC,gCACE,oCAAC,QAAK,OAAO,MAAM,WAAS,OAAK,GAAO,iBAAW,KAClE,oCAAC,QAAK,OAAO,MAAM,SAAO,KAAG,GAAO,SACtC,CACF;AAAA,EACF;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,10 @@
1
1
  import React, { useState, useEffect, useCallback } from "react";
2
2
  import { Box, Text, useInput } from "ink";
3
- import { loadAllPlugins, togglePluginEnabled, getPlugin } from "../../utils/pluginLoader.js";
3
+ import {
4
+ loadAllPlugins,
5
+ togglePluginEnabled,
6
+ getPlugin
7
+ } from "../../utils/pluginLoader.js";
4
8
  import { getTheme } from "../../utils/theme.js";
5
9
  const InstalledPluginsByMarketplace = ({ marketplace, onNavigate, onBack }) => {
6
10
  const [plugins, setPlugins] = useState([]);
@@ -37,7 +41,9 @@ const InstalledPluginsByMarketplace = ({ marketplace, onNavigate, onBack }) => {
37
41
  const handleToggleEnabled = useCallback(() => {
38
42
  if (plugins[selectedIndex]) {
39
43
  try {
40
- const newState = togglePluginEnabled(plugins[selectedIndex].manifest.name);
44
+ const newState = togglePluginEnabled(
45
+ plugins[selectedIndex].manifest.name
46
+ );
41
47
  loadPlugins();
42
48
  } catch (error) {
43
49
  console.error("Error toggling plugin:", error);
@@ -114,7 +120,7 @@ const InstalledPluginsByMarketplace = ({ marketplace, onNavigate, onBack }) => {
114
120
  }
115
121
  });
116
122
  if (showConfirm && confirmAction === "uninstall") {
117
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", padding: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.warning }, "Confirm Uninstall Mark"), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Text, null, 'Mark plugin "', plugins[selectedIndex]?.manifest.name, '" for uninstallation?'), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "This will mark the plugin for removal. Use batch actions to complete."), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "Y"), "es / ", /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "N"), "o"));
123
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", padding: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.warning }, "Confirm Uninstall Mark"), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Text, null, 'Mark plugin "', plugins[selectedIndex]?.manifest.name, '" for uninstallation?'), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "This will mark the plugin for removal. Use batch actions to complete."), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "Y"), "es /", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "N"), "o"));
118
124
  }
119
125
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", padding: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, marketplace.name, " \u203A Manage Plugins (", plugins.length, ")"), /* @__PURE__ */ React.createElement(Text, null, ""), plugins.length === 0 ? /* @__PURE__ */ React.createElement(Box, { marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: theme.warning }, "No plugins installed from this marketplace")) : plugins.map((plugin, index) => {
120
126
  const isSelected = index === selectedIndex;
@@ -122,11 +128,21 @@ const InstalledPluginsByMarketplace = ({ marketplace, onNavigate, onBack }) => {
122
128
  const marks = [];
123
129
  if (plugin.markedForUpdate) marks.push("\u2B06");
124
130
  if (plugin.markedForUninstall) marks.push("\u2717");
125
- return /* @__PURE__ */ React.createElement(Box, { key: plugin.manifest.name, flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: isSelected ? theme.success : void 0 }, isSelected ? "\u276F " : " ", statusIcon, " ", plugin.manifest.displayName || plugin.manifest.name), marks.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.warning }, " ", marks.join(" "))), /* @__PURE__ */ React.createElement(Box, { marginLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, plugin.manifest.description, " \xB7 v", plugin.manifest.version)), isSelected && /* @__PURE__ */ React.createElement(Box, { marginLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Components:", " ", [
126
- plugin.agents.length > 0 && `${plugin.agents.length} agent(s)`,
127
- plugin.commands.length > 0 && `${plugin.commands.length} command(s)`,
128
- plugin.skills.length > 0 && `${plugin.skills.length} skill(s)`
129
- ].filter(Boolean).join(", ") || "none")));
131
+ return /* @__PURE__ */ React.createElement(
132
+ Box,
133
+ {
134
+ key: plugin.manifest.name,
135
+ flexDirection: "column",
136
+ marginBottom: 1
137
+ },
138
+ /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: isSelected ? theme.success : void 0 }, isSelected ? "\u276F " : " ", statusIcon, " ", plugin.manifest.displayName || plugin.manifest.name), marks.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.warning }, " ", marks.join(" "))),
139
+ /* @__PURE__ */ React.createElement(Box, { marginLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, plugin.manifest.description, " \xB7 v", plugin.manifest.version)),
140
+ isSelected && /* @__PURE__ */ React.createElement(Box, { marginLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Components:", " ", [
141
+ plugin.agents.length > 0 && `${plugin.agents.length} agent(s)`,
142
+ plugin.commands.length > 0 && `${plugin.commands.length} command(s)`,
143
+ plugin.skills.length > 0 && `${plugin.skills.length} skill(s)`
144
+ ].filter(Boolean).join(", ") || "none"))
145
+ );
130
146
  }), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Box, { marginLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Space Toggle \xB7 U Mark Update \xB7 D/Del Mark Uninstall"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Enter Details \xB7 Esc Back")));
131
147
  };
132
148
  export {