@within-7/minto 0.3.10 → 0.4.1

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 (306) hide show
  1. package/dist/Tool.js.map +2 -2
  2. package/dist/commands/agents/AgentsCommand.js +2 -2
  3. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  4. package/dist/commands/ctx_viz.js +1 -1
  5. package/dist/commands/effort.js +87 -0
  6. package/dist/commands/effort.js.map +7 -0
  7. package/dist/commands/export.js +19 -9
  8. package/dist/commands/export.js.map +2 -2
  9. package/dist/commands/ide.js +18 -0
  10. package/dist/commands/ide.js.map +7 -0
  11. package/dist/commands/mcp-interactive.js +14 -8
  12. package/dist/commands/mcp-interactive.js.map +2 -2
  13. package/dist/commands/memory.js +168 -0
  14. package/dist/commands/memory.js.map +7 -0
  15. package/dist/commands/model.js +45 -2
  16. package/dist/commands/model.js.map +2 -2
  17. package/dist/commands/outputStyle.js +64 -0
  18. package/dist/commands/outputStyle.js.map +7 -0
  19. package/dist/commands/plugin/utils.js +33 -1
  20. package/dist/commands/plugin/utils.js.map +2 -2
  21. package/dist/commands/plugin.js +10 -1
  22. package/dist/commands/plugin.js.map +2 -2
  23. package/dist/commands/refreshCommands.js +2 -0
  24. package/dist/commands/refreshCommands.js.map +2 -2
  25. package/dist/commands/review.js +51 -0
  26. package/dist/commands/review.js.map +7 -0
  27. package/dist/commands/terminalSetup.js +6 -0
  28. package/dist/commands/terminalSetup.js.map +2 -2
  29. package/dist/commands/undo.js +8 -0
  30. package/dist/commands/undo.js.map +2 -2
  31. package/dist/commands/vim.js +22 -0
  32. package/dist/commands/vim.js.map +7 -0
  33. package/dist/commands.js +12 -0
  34. package/dist/commands.js.map +2 -2
  35. package/dist/components/HighlightedCode.js +1 -0
  36. package/dist/components/HighlightedCode.js.map +2 -2
  37. package/dist/components/ModelSelector/ModelSelector.js +250 -143
  38. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  39. package/dist/components/PromptInput.js +21 -6
  40. package/dist/components/PromptInput.js.map +2 -2
  41. package/dist/components/PulseLabel.js +44 -0
  42. package/dist/components/PulseLabel.js.map +7 -0
  43. package/dist/components/RequestStatusIndicator.js +1 -1
  44. package/dist/components/RequestStatusIndicator.js.map +1 -1
  45. package/dist/components/Spinner.js +12 -42
  46. package/dist/components/Spinner.js.map +3 -3
  47. package/dist/components/StartupStatus.js +57 -0
  48. package/dist/components/StartupStatus.js.map +7 -0
  49. package/dist/components/SubagentBlock.js +43 -6
  50. package/dist/components/SubagentBlock.js.map +2 -2
  51. package/dist/components/TabbedListView/TabBar.js +13 -8
  52. package/dist/components/TabbedListView/TabBar.js.map +2 -2
  53. package/dist/components/TabbedListView/TabbedListView.js +1 -1
  54. package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
  55. package/dist/components/TodoPanel.js +1 -1
  56. package/dist/components/TodoPanel.js.map +1 -1
  57. package/dist/components/ToolUseLoader.js +5 -0
  58. package/dist/components/ToolUseLoader.js.map +2 -2
  59. package/dist/components/TrustDialog.js +0 -2
  60. package/dist/components/TrustDialog.js.map +2 -2
  61. package/dist/components/messages/TaskInModuleView.js +1 -1
  62. package/dist/components/messages/TaskInModuleView.js.map +2 -2
  63. package/dist/components/messages/TaskToolMessage.js +1 -1
  64. package/dist/components/messages/TaskToolMessage.js.map +2 -2
  65. package/dist/components/messages/UserPromptMessage.js +6 -1
  66. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  67. package/dist/constants/modelCapabilities.js +103 -18
  68. package/dist/constants/modelCapabilities.js.map +2 -2
  69. package/dist/constants/product.js +2 -0
  70. package/dist/constants/product.js.map +2 -2
  71. package/dist/constants/prompts/agentPrompt.js +30 -0
  72. package/dist/constants/prompts/agentPrompt.js.map +7 -0
  73. package/dist/constants/prompts/codeConventions.js +27 -0
  74. package/dist/constants/prompts/codeConventions.js.map +7 -0
  75. package/dist/constants/prompts/doingTasks.js +15 -0
  76. package/dist/constants/prompts/doingTasks.js.map +7 -0
  77. package/dist/constants/prompts/envInfo.js +17 -0
  78. package/dist/constants/prompts/envInfo.js.map +7 -0
  79. package/dist/constants/prompts/executingWithCare.js +17 -0
  80. package/dist/constants/prompts/executingWithCare.js.map +7 -0
  81. package/dist/constants/prompts/identity.js +10 -0
  82. package/dist/constants/prompts/identity.js.map +7 -0
  83. package/dist/constants/prompts/index.js +78 -0
  84. package/dist/constants/prompts/index.js.map +7 -0
  85. package/dist/constants/prompts/taskManagement.js +60 -0
  86. package/dist/constants/prompts/taskManagement.js.map +7 -0
  87. package/dist/constants/prompts/toneAndStyle.js +62 -0
  88. package/dist/constants/prompts/toneAndStyle.js.map +7 -0
  89. package/dist/constants/prompts/toolUsagePolicy.js +38 -0
  90. package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
  91. package/dist/constants/prompts.js +5 -176
  92. package/dist/constants/prompts.js.map +2 -2
  93. package/dist/constants/providerRegistry.js +235 -0
  94. package/dist/constants/providerRegistry.js.map +7 -0
  95. package/dist/constants/providers.js +35 -0
  96. package/dist/constants/providers.js.map +7 -0
  97. package/dist/context/PermissionContext.js +0 -1
  98. package/dist/context/PermissionContext.js.map +2 -2
  99. package/dist/context.js +87 -31
  100. package/dist/context.js.map +2 -2
  101. package/dist/core/backupHook.js +2 -2
  102. package/dist/core/backupHook.js.map +2 -2
  103. package/dist/core/config/defaults.js +4 -1
  104. package/dist/core/config/defaults.js.map +2 -2
  105. package/dist/core/config/schema.js +7 -1
  106. package/dist/core/config/schema.js.map +2 -2
  107. package/dist/core/costTracker.js +18 -0
  108. package/dist/core/costTracker.js.map +2 -2
  109. package/dist/core/index.js +0 -1
  110. package/dist/core/index.js.map +2 -2
  111. package/dist/core/tokenStatsManager.js +22 -4
  112. package/dist/core/tokenStatsManager.js.map +2 -2
  113. package/dist/entrypoints/cli.js +65 -84
  114. package/dist/entrypoints/cli.js.map +2 -2
  115. package/dist/hooks/useAgentTokenStats.js +1 -1
  116. package/dist/hooks/useAgentTokenStats.js.map +2 -2
  117. package/dist/hooks/useAgentTranscripts.js +2 -1
  118. package/dist/hooks/useAgentTranscripts.js.map +2 -2
  119. package/dist/hooks/useBackgroundShells.js +29 -0
  120. package/dist/hooks/useBackgroundShells.js.map +7 -0
  121. package/dist/hooks/useCanUseTool.js +1 -1
  122. package/dist/hooks/useCanUseTool.js.map +2 -2
  123. package/dist/hooks/useDeferredLoading.js +64 -0
  124. package/dist/hooks/useDeferredLoading.js.map +7 -0
  125. package/dist/hooks/useHookStatus.js +1 -1
  126. package/dist/hooks/useHookStatus.js.map +2 -2
  127. package/dist/hooks/useSessionTracking.js +55 -0
  128. package/dist/hooks/useSessionTracking.js.map +7 -0
  129. package/dist/hooks/useTerminalSize.js +21 -0
  130. package/dist/hooks/useTerminalSize.js.map +2 -2
  131. package/dist/hooks/useTextInput.js +1 -0
  132. package/dist/hooks/useTextInput.js.map +2 -2
  133. package/dist/hooks/useUnifiedCompletion.js +3 -2
  134. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  135. package/dist/i18n/locales/en.js +8 -9
  136. package/dist/i18n/locales/en.js.map +2 -2
  137. package/dist/i18n/locales/zh-CN.js +8 -9
  138. package/dist/i18n/locales/zh-CN.js.map +2 -2
  139. package/dist/i18n/types.js.map +1 -1
  140. package/dist/messages.js +41 -17
  141. package/dist/messages.js.map +2 -2
  142. package/dist/permissions.js +94 -1
  143. package/dist/permissions.js.map +2 -2
  144. package/dist/query.js +27 -19
  145. package/dist/query.js.map +2 -2
  146. package/dist/screens/REPL.js +83 -74
  147. package/dist/screens/REPL.js.map +2 -2
  148. package/dist/services/adapters/responsesAPI.js +6 -0
  149. package/dist/services/adapters/responsesAPI.js.map +2 -2
  150. package/dist/services/agentTeams/index.js +35 -0
  151. package/dist/services/agentTeams/index.js.map +7 -0
  152. package/dist/services/agentTeams/mailbox.js +114 -0
  153. package/dist/services/agentTeams/mailbox.js.map +7 -0
  154. package/dist/services/agentTeams/teamManager.js +149 -0
  155. package/dist/services/agentTeams/teamManager.js.map +7 -0
  156. package/dist/services/agentTeams/teamTaskStore.js +114 -0
  157. package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
  158. package/dist/services/agentTeams/teammateSpawner.js +80 -0
  159. package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
  160. package/dist/services/checkpointManager.js +16 -3
  161. package/dist/services/checkpointManager.js.map +2 -2
  162. package/dist/services/claude.js +19 -1728
  163. package/dist/services/claude.js.map +3 -3
  164. package/dist/services/gpt5ConnectionTest.js +4 -2
  165. package/dist/services/gpt5ConnectionTest.js.map +2 -2
  166. package/dist/services/hookExecutor.js +411 -127
  167. package/dist/services/hookExecutor.js.map +2 -2
  168. package/dist/services/llm/anthropicProvider.js +807 -0
  169. package/dist/services/llm/anthropicProvider.js.map +7 -0
  170. package/dist/services/llm/dispatch.js +218 -0
  171. package/dist/services/llm/dispatch.js.map +7 -0
  172. package/dist/services/llm/index.js +44 -0
  173. package/dist/services/llm/index.js.map +7 -0
  174. package/dist/services/llm/mintoContext.js +69 -0
  175. package/dist/services/llm/mintoContext.js.map +7 -0
  176. package/dist/services/llm/openaiProvider.js +622 -0
  177. package/dist/services/llm/openaiProvider.js.map +7 -0
  178. package/dist/services/llm/types.js +157 -0
  179. package/dist/services/llm/types.js.map +7 -0
  180. package/dist/services/mcpClient.js +183 -33
  181. package/dist/services/mcpClient.js.map +2 -2
  182. package/dist/services/notifier.js +14 -0
  183. package/dist/services/notifier.js.map +2 -2
  184. package/dist/services/oauth.js +4 -2
  185. package/dist/services/oauth.js.map +2 -2
  186. package/dist/services/openai.js +66 -56
  187. package/dist/services/openai.js.map +3 -3
  188. package/dist/services/outputStyles.js +102 -21
  189. package/dist/services/outputStyles.js.map +2 -2
  190. package/dist/services/plugins/skillMarketplace.js +4 -1
  191. package/dist/services/plugins/skillMarketplace.js.map +2 -2
  192. package/dist/services/sentry.js +1 -1
  193. package/dist/services/sentry.js.map +2 -2
  194. package/dist/services/sessionMemory.js +16 -3
  195. package/dist/services/sessionMemory.js.map +2 -2
  196. package/dist/services/systemReminder.js +350 -3
  197. package/dist/services/systemReminder.js.map +2 -2
  198. package/dist/services/taskStore.js +19 -0
  199. package/dist/services/taskStore.js.map +2 -2
  200. package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
  201. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
  202. package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
  203. package/dist/tools/BashTool/BashTool.js +28 -0
  204. package/dist/tools/BashTool/BashTool.js.map +2 -2
  205. package/dist/tools/FileEditTool/FileEditTool.js +1 -1
  206. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  207. package/dist/tools/FileReadTool/FileReadTool.js +14 -0
  208. package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
  209. package/dist/tools/FileWriteTool/FileWriteTool.js +3 -1
  210. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  211. package/dist/tools/GlobTool/GlobTool.js.map +1 -1
  212. package/dist/tools/GrepTool/GrepTool.js.map +1 -1
  213. package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
  214. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
  215. package/dist/tools/LspTool/LspTool.js +11 -2
  216. package/dist/tools/LspTool/LspTool.js.map +2 -2
  217. package/dist/tools/MCPTool/MCPTool.js.map +1 -1
  218. package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
  219. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  220. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
  221. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  222. package/dist/tools/MultiEditTool/MultiEditTool.js.map +1 -1
  223. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +1 -1
  224. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
  225. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
  226. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
  227. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
  228. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
  229. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
  230. package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
  231. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
  232. package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
  233. package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
  234. package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
  235. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
  236. package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
  237. package/dist/tools/TaskTool/TaskTool.js +75 -5
  238. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  239. package/dist/tools/TaskTool/prompt.js +12 -6
  240. package/dist/tools/TaskTool/prompt.js.map +2 -2
  241. package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
  242. package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
  243. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
  244. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
  245. package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
  246. package/dist/tools/WebSearchTool/searchProviders.js +2 -1
  247. package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
  248. package/dist/tools/lsTool/lsTool.js.map +2 -2
  249. package/dist/tools/lsTool/prompt.js.map +1 -1
  250. package/dist/tools.js +14 -3
  251. package/dist/tools.js.map +2 -2
  252. package/dist/types/PermissionMode.js +21 -1
  253. package/dist/types/PermissionMode.js.map +2 -2
  254. package/dist/types/agentTeams.js +1 -0
  255. package/dist/types/agentTeams.js.map +7 -0
  256. package/dist/types/hooks.js +8 -2
  257. package/dist/types/hooks.js.map +2 -2
  258. package/dist/types/plugin.js +1 -1
  259. package/dist/types/plugin.js.map +2 -2
  260. package/dist/utils/agentLoader.js +25 -3
  261. package/dist/utils/agentLoader.js.map +2 -2
  262. package/dist/utils/animationManager.js +1 -1
  263. package/dist/utils/animationManager.js.map +2 -2
  264. package/dist/utils/ask.js +1 -1
  265. package/dist/utils/async.js +5 -1
  266. package/dist/utils/async.js.map +2 -2
  267. package/dist/utils/autoCompactCore.js +60 -0
  268. package/dist/utils/autoCompactCore.js.map +2 -2
  269. package/dist/utils/config.js +26 -128
  270. package/dist/utils/config.js.map +2 -2
  271. package/dist/utils/configSchema.js +227 -0
  272. package/dist/utils/configSchema.js.map +7 -0
  273. package/dist/utils/debugLogger.js.map +2 -2
  274. package/dist/utils/env.js +4 -3
  275. package/dist/utils/env.js.map +2 -2
  276. package/dist/utils/envConfig.js +34 -0
  277. package/dist/utils/envConfig.js.map +3 -3
  278. package/dist/utils/gpt5.js +146 -0
  279. package/dist/utils/gpt5.js.map +7 -0
  280. package/dist/utils/hookManager.js +374 -140
  281. package/dist/utils/hookManager.js.map +2 -2
  282. package/dist/utils/markdown.js +47 -0
  283. package/dist/utils/markdown.js.map +2 -2
  284. package/dist/utils/memoizeWithTTL.js +25 -0
  285. package/dist/utils/memoizeWithTTL.js.map +7 -0
  286. package/dist/utils/model.js +34 -9
  287. package/dist/utils/model.js.map +2 -2
  288. package/dist/utils/pluginInstaller.js +34 -5
  289. package/dist/utils/pluginInstaller.js.map +2 -2
  290. package/dist/utils/pluginLoader.js +201 -32
  291. package/dist/utils/pluginLoader.js.map +2 -2
  292. package/dist/utils/safeFetch.js +45 -0
  293. package/dist/utils/safeFetch.js.map +7 -0
  294. package/dist/utils/skillLoader.js +59 -6
  295. package/dist/utils/skillLoader.js.map +2 -2
  296. package/dist/utils/streamingState.js +52 -0
  297. package/dist/utils/streamingState.js.map +7 -0
  298. package/dist/utils/style.js +6 -3
  299. package/dist/utils/style.js.map +2 -2
  300. package/dist/utils/teamConfig.js +9 -3
  301. package/dist/utils/teamConfig.js.map +2 -2
  302. package/dist/utils/toolRiskClassification.js +0 -6
  303. package/dist/utils/toolRiskClassification.js.map +2 -2
  304. package/dist/version.js +2 -2
  305. package/dist/version.js.map +1 -1
  306. 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 * 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 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 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 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 refreshMCPConnections()\n await loadServers()\n setStatusOverlay({\n type: 'success',\n message: t('commands.mcp.refreshSuccess'),\n })\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 }\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": "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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": "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",
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
+ }
@@ -12,6 +12,7 @@ import { t } from "../i18n/index.js";
12
12
  const ID_MANAGE_LIBRARY = "__manage_library__";
13
13
  const ID_ADD_NEW = "__add_new__";
14
14
  const ID_CLEAR = "__clear__";
15
+ const ID_EDIT = "__edit__";
15
16
  const ID_DELETE = "__delete__";
16
17
  const ID_BACK = "__back__";
17
18
  const ID_CONFIRM_YES = "__yes__";
@@ -120,6 +121,15 @@ function ModelCommand({ onClose, abortController }) {
120
121
  {
121
122
  modelName: phase.modelName,
122
123
  modelLabel: phase.modelLabel,
124
+ onEdit: () => {
125
+ enableConfigs();
126
+ abortController?.abort?.();
127
+ setPhase({
128
+ type: "edit-model",
129
+ modelName: phase.modelName,
130
+ modelLabel: phase.modelLabel
131
+ });
132
+ },
123
133
  onDelete: () => setPhase({
124
134
  type: "confirm-delete",
125
135
  modelName: phase.modelName,
@@ -182,6 +192,32 @@ function ModelCommand({ onClose, abortController }) {
182
192
  }
183
193
  );
184
194
  }
195
+ if (phase.type === "edit-model") {
196
+ const modelManager = getModelManager();
197
+ const profile = modelManager.getAvailableModels().find((m) => m.modelName === phase.modelName);
198
+ if (!profile) {
199
+ setPhase({ type: "library" });
200
+ return null;
201
+ }
202
+ return /* @__PURE__ */ React.createElement(
203
+ ModelSelector,
204
+ {
205
+ onDone: () => {
206
+ refreshModels();
207
+ setPhase({ type: "library" });
208
+ },
209
+ onCancel: () => setPhase({
210
+ type: "model-actions",
211
+ modelName: phase.modelName,
212
+ modelLabel: phase.modelLabel
213
+ }),
214
+ skipModelType: true,
215
+ isOnboarding: false,
216
+ abortController: new AbortController(),
217
+ editingModel: profile
218
+ }
219
+ );
220
+ }
185
221
  return null;
186
222
  }
187
223
  function MainPhase({
@@ -353,10 +389,15 @@ function LibraryPhase({
353
389
  function ModelActionsPhase({
354
390
  modelName,
355
391
  modelLabel,
392
+ onEdit,
356
393
  onDelete,
357
394
  onClose
358
395
  }) {
359
396
  const items = [
397
+ {
398
+ id: ID_EDIT,
399
+ label: t("commands.model.editModel")
400
+ },
360
401
  {
361
402
  id: ID_DELETE,
362
403
  label: t("common.delete"),
@@ -370,13 +411,15 @@ function ModelActionsPhase({
370
411
  ];
371
412
  const handleSelect = useCallback(
372
413
  (item) => {
373
- if (item.id === ID_DELETE) {
414
+ if (item.id === ID_EDIT) {
415
+ onEdit();
416
+ } else if (item.id === ID_DELETE) {
374
417
  onDelete();
375
418
  } else {
376
419
  onClose();
377
420
  }
378
421
  },
379
- [onDelete, onClose]
422
+ [onEdit, onDelete, onClose]
380
423
  );
381
424
  return /* @__PURE__ */ React.createElement(
382
425
  SimpleSelector,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/model.tsx"],
4
- "sourcesContent": ["/**\n * Model Command\n *\n * Interactive model configuration using SimpleSelector phase state machine.\n *\n * Phase flow:\n * main \u2192 (select pointer) \u2192 assign \u2192 (select model) \u2192 main\n * main \u2192 (Manage Library) \u2192 library \u2192 (select model) \u2192 model-actions\n * \u2193\n * confirm-delete \u2192 library\n * library \u2192 (+ Add New) \u2192 add-model \u2192 library\n */\n\nimport React, { useState, useMemo, useCallback } from 'react'\nimport { SimpleSelector } from '@components/SimpleSelector'\nimport type { SelectorItem, StatusOverlay } from '@components/SimpleSelector'\nimport { ModelSelector } from '@components/ModelSelector'\nimport { enableConfigs } from '@utils/config'\nimport {\n ModelPointerType,\n setModelPointer,\n getGlobalConfig,\n} from '@utils/config'\nimport { getModelManager, reloadModelManager } from '@utils/model'\nimport { triggerModelConfigChange } from '@messages'\nimport { t } from '@i18n'\nimport type { Command } from '@commands'\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype ModelPhase =\n | { type: 'main' }\n | { type: 'assign'; pointer: ModelPointerType }\n | { type: 'library' }\n | { type: 'model-actions'; modelName: string; modelLabel: string }\n | { type: 'confirm-delete'; modelName: string; modelLabel: string }\n | { type: 'add-model' }\n\n// Special item IDs\nconst ID_MANAGE_LIBRARY = '__manage_library__'\nconst ID_ADD_NEW = '__add_new__'\nconst ID_CLEAR = '__clear__'\nconst ID_DELETE = '__delete__'\nconst ID_BACK = '__back__'\nconst ID_CONFIRM_YES = '__yes__'\nconst ID_CONFIRM_NO = '__no__'\n\nconst POINTER_TYPES: ModelPointerType[] = [\n 'main',\n 'task',\n 'reasoning',\n 'quick',\n 'compact',\n]\n\nconst POINTER_LABELS: Record<ModelPointerType, string> = {\n main: 'Main',\n task: 'Task',\n reasoning: 'Reasoning',\n quick: 'Quick',\n compact: 'Compact',\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction getPointerDescription(pointer: ModelPointerType): string {\n const key = `ui.modelConfig.${pointer}Description` as const\n return t(key)\n}\n\n// =============================================================================\n// Main Component\n// =============================================================================\n\ntype Props = {\n onClose: () => void\n abortController?: AbortController\n}\n\nfunction ModelCommand({ onClose, abortController }: Props): React.ReactNode {\n const [phase, setPhase] = useState<ModelPhase>({ type: 'main' })\n const [statusOverlay, setStatusOverlay] = useState<StatusOverlay | null>(null)\n const [refreshKey, setRefreshKey] = useState(0)\n\n // Reload models and trigger config change\n const refreshModels = useCallback(() => {\n reloadModelManager()\n triggerModelConfigChange()\n setRefreshKey(prev => prev + 1)\n }, [])\n\n // Show a temporary success overlay then transition\n const showSuccessAndGo = useCallback(\n (message: string, nextPhase: ModelPhase) => {\n setStatusOverlay({ type: 'success', message })\n setTimeout(() => {\n setStatusOverlay(null)\n setPhase(nextPhase)\n }, 800)\n },\n [],\n )\n\n // \u2500\u2500\u2500 Phase: main \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 if (phase.type === 'main') {\n return (\n <MainPhase\n refreshKey={refreshKey}\n statusOverlay={statusOverlay}\n onSelectPointer={pointer => setPhase({ type: 'assign', pointer })}\n onManageLibrary={() => setPhase({ type: 'library' })}\n onClose={onClose}\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: assign \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 if (phase.type === 'assign') {\n return (\n <AssignPhase\n pointer={phase.pointer}\n refreshKey={refreshKey}\n statusOverlay={statusOverlay}\n onAssign={(pointer, modelName) => {\n setModelPointer(pointer, modelName)\n refreshModels()\n showSuccessAndGo(\n t('commands.model.pointerUpdated').replace(\n '{pointer}',\n POINTER_LABELS[pointer],\n ),\n { type: 'main' },\n )\n }}\n onClear={pointer => {\n setModelPointer(pointer, '')\n refreshModels()\n showSuccessAndGo(\n t('commands.model.pointerCleared').replace(\n '{pointer}',\n POINTER_LABELS[pointer],\n ),\n { type: 'main' },\n )\n }}\n onClose={() => setPhase({ type: 'main' })}\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: library \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 if (phase.type === 'library') {\n return (\n <LibraryPhase\n refreshKey={refreshKey}\n statusOverlay={statusOverlay}\n onSelectModel={(modelName, modelLabel) =>\n setPhase({ type: 'model-actions', modelName, modelLabel })\n }\n onAddNew={() => {\n enableConfigs()\n abortController?.abort?.()\n setPhase({ type: 'add-model' })\n }}\n onClose={() => setPhase({ type: 'main' })}\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: model-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\n if (phase.type === 'model-actions') {\n return (\n <ModelActionsPhase\n modelName={phase.modelName}\n modelLabel={phase.modelLabel}\n onDelete={() =>\n setPhase({\n type: 'confirm-delete',\n modelName: phase.modelName,\n modelLabel: phase.modelLabel,\n })\n }\n onClose={() => setPhase({ type: 'library' })}\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: confirm-delete \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 if (phase.type === 'confirm-delete') {\n return (\n <ConfirmDeletePhase\n modelName={phase.modelName}\n modelLabel={phase.modelLabel}\n statusOverlay={statusOverlay}\n onConfirm={() => {\n try {\n const modelManager = getModelManager()\n modelManager.removeModel(phase.modelName)\n refreshModels()\n showSuccessAndGo(t('commands.model.modelDeleted'), {\n type: 'library',\n })\n } catch {\n setStatusOverlay({\n type: 'error',\n message: t('commands.model.deleteFailed'),\n })\n setTimeout(() => {\n setStatusOverlay(null)\n setPhase({\n type: 'model-actions',\n modelName: phase.modelName,\n modelLabel: phase.modelLabel,\n })\n }, 1500)\n }\n }}\n onCancel={() =>\n setPhase({\n type: 'model-actions',\n modelName: phase.modelName,\n modelLabel: phase.modelLabel,\n })\n }\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: add-model \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 if (phase.type === 'add-model') {\n return (\n <ModelSelector\n onDone={() => {\n refreshModels()\n setPhase({ type: 'library' })\n }}\n onCancel={() => setPhase({ type: 'library' })}\n skipModelType={true}\n isOnboarding={false}\n abortController={new AbortController()}\n />\n )\n }\n\n // Fallback (shouldn't happen)\n return null\n}\n\n// =============================================================================\n// Phase Components\n// =============================================================================\n\nfunction MainPhase({\n refreshKey,\n statusOverlay,\n onSelectPointer,\n onManageLibrary,\n onClose,\n}: {\n refreshKey: number\n statusOverlay: StatusOverlay | null\n onSelectPointer: (pointer: ModelPointerType) => void\n onManageLibrary: () => void\n onClose: () => void\n}) {\n const items = useMemo((): SelectorItem[] => {\n const config = getGlobalConfig()\n const modelManager = getModelManager()\n const models = modelManager.getAvailableModels()\n\n const pointerItems: SelectorItem[] = POINTER_TYPES.map(pointer => {\n const assignedModelName = config.modelPointers?.[pointer] || ''\n const model = models.find(m => m.modelName === assignedModelName)\n const description = model\n ? `${model.name} (${model.provider})`\n : getPointerDescription(pointer)\n\n return {\n id: pointer,\n label: POINTER_LABELS[pointer],\n description,\n category: t('commands.model.pointersCategory'),\n statusIcon: model ? '\\u2713' : undefined,\n statusColor: model ? '#4EBA65' : undefined,\n }\n })\n\n const actionItems: SelectorItem[] = [\n {\n id: ID_MANAGE_LIBRARY,\n label: t('commands.model.modelLibrary'),\n description: t('commands.model.modelLibrarySubtitle'),\n category: t('commands.model.actionsCategory'),\n },\n ]\n\n return [...pointerItems, ...actionItems]\n }, [refreshKey])\n\n const handleSelect = useCallback(\n (item: SelectorItem) => {\n if (item.id === ID_MANAGE_LIBRARY) {\n onManageLibrary()\n } else {\n onSelectPointer(item.id as ModelPointerType)\n }\n },\n [onSelectPointer, onManageLibrary],\n )\n\n return (\n <SimpleSelector\n title={t('commands.model.title')}\n items={items}\n onSelect={handleSelect}\n onClose={onClose}\n groupByCategory={true}\n statusOverlay={statusOverlay}\n />\n )\n}\n\nfunction AssignPhase({\n pointer,\n refreshKey,\n statusOverlay,\n onAssign,\n onClear,\n onClose,\n}: {\n pointer: ModelPointerType\n refreshKey: number\n statusOverlay: StatusOverlay | null\n onAssign: (pointer: ModelPointerType, modelName: string) => void\n onClear: (pointer: ModelPointerType) => void\n onClose: () => void\n}) {\n const items = useMemo((): SelectorItem[] => {\n const config = getGlobalConfig()\n const modelManager = getModelManager()\n const models = modelManager.getAvailableModels()\n const currentAssignment = config.modelPointers?.[pointer] || ''\n\n const modelItems: SelectorItem[] = models.map(model => ({\n id: model.modelName,\n label: model.name,\n description: `${model.provider}: ${model.modelName}`,\n isCurrent: model.modelName === currentAssignment,\n }))\n\n // Add \"Clear Assignment\" option if there's a current assignment\n if (currentAssignment) {\n modelItems.push({\n id: ID_CLEAR,\n label: t('commands.model.clearAssignment'),\n statusIcon: '\\u2715',\n statusColor: '#FF6B80',\n })\n }\n\n return modelItems\n }, [pointer, refreshKey])\n\n const handleSelect = useCallback(\n (item: SelectorItem) => {\n if (item.id === ID_CLEAR) {\n onClear(pointer)\n } else {\n onAssign(pointer, item.id)\n }\n },\n [pointer, onAssign, onClear],\n )\n\n return (\n <SimpleSelector\n title={t('commands.model.selectModel').replace(\n '{pointer}',\n POINTER_LABELS[pointer],\n )}\n items={items}\n onSelect={handleSelect}\n onClose={onClose}\n statusOverlay={statusOverlay}\n />\n )\n}\n\nfunction LibraryPhase({\n refreshKey,\n statusOverlay,\n onSelectModel,\n onAddNew,\n onClose,\n}: {\n refreshKey: number\n statusOverlay: StatusOverlay | null\n onSelectModel: (modelName: string, modelLabel: string) => void\n onAddNew: () => void\n onClose: () => void\n}) {\n const items = useMemo((): SelectorItem[] => {\n const config = getGlobalConfig()\n const modelManager = getModelManager()\n const models = modelManager.getAvailableModels()\n\n const modelItems: SelectorItem[] = models.map(model => {\n // Find which pointers use this model\n const usedBy: string[] = []\n POINTER_TYPES.forEach(p => {\n if (config.modelPointers?.[p] === model.modelName) {\n usedBy.push(POINTER_LABELS[p])\n }\n })\n const usageDesc = usedBy.length > 0 ? `[${usedBy.join(', ')}]` : ''\n\n return {\n id: model.modelName,\n label: model.name,\n description: `${model.provider}${usageDesc ? ' ' + usageDesc : ''}`,\n statusIcon: usedBy.length > 0 ? '\\u2713' : undefined,\n statusColor: usedBy.length > 0 ? '#4EBA65' : undefined,\n data: { modelLabel: model.name },\n }\n })\n\n modelItems.push({\n id: ID_ADD_NEW,\n label: t('commands.model.addNewModel'),\n })\n\n return modelItems\n }, [refreshKey])\n\n const handleSelect = useCallback(\n (item: SelectorItem) => {\n if (item.id === ID_ADD_NEW) {\n onAddNew()\n } else {\n const data = item.data as { modelLabel: string } | undefined\n onSelectModel(item.id, data?.modelLabel || item.label)\n }\n },\n [onSelectModel, onAddNew],\n )\n\n return (\n <SimpleSelector\n title={t('commands.model.modelLibrary')}\n subtitle={t('commands.model.modelLibrarySubtitle')}\n items={items}\n onSelect={handleSelect}\n onClose={onClose}\n statusOverlay={statusOverlay}\n />\n )\n}\n\nfunction ModelActionsPhase({\n modelName,\n modelLabel,\n onDelete,\n onClose,\n}: {\n modelName: string\n modelLabel: string\n onDelete: () => void\n onClose: () => void\n}) {\n const items: SelectorItem[] = [\n {\n id: ID_DELETE,\n label: t('common.delete'),\n statusIcon: '\\u2715',\n statusColor: '#FF6B80',\n },\n {\n id: ID_BACK,\n label: t('common.back'),\n },\n ]\n\n const handleSelect = useCallback(\n (item: SelectorItem) => {\n if (item.id === ID_DELETE) {\n onDelete()\n } else {\n onClose()\n }\n },\n [onDelete, onClose],\n )\n\n return (\n <SimpleSelector\n title={t('commands.model.modelActions').replace('{model}', modelLabel)}\n items={items}\n onSelect={handleSelect}\n onClose={onClose}\n />\n )\n}\n\nfunction ConfirmDeletePhase({\n modelName,\n modelLabel,\n statusOverlay,\n onConfirm,\n onCancel,\n}: {\n modelName: string\n modelLabel: string\n statusOverlay: StatusOverlay | null\n onConfirm: () => void\n onCancel: () => void\n}) {\n const items: SelectorItem[] = [\n {\n id: ID_CONFIRM_YES,\n label: t('commands.model.confirmDeleteYes'),\n statusIcon: '\\u2715',\n statusColor: '#FF6B80',\n },\n {\n id: ID_CONFIRM_NO,\n label: t('commands.model.confirmDeleteNo'),\n },\n ]\n\n const handleSelect = useCallback(\n (item: SelectorItem) => {\n if (item.id === ID_CONFIRM_YES) {\n onConfirm()\n } else {\n onCancel()\n }\n },\n [onConfirm, onCancel],\n )\n\n return (\n <SimpleSelector\n title={t('commands.model.confirmDeleteTitle').replace(\n '{model}',\n modelLabel,\n )}\n items={items}\n onSelect={handleSelect}\n onClose={onCancel}\n statusOverlay={statusOverlay}\n />\n )\n}\n\n// =============================================================================\n// Command Export\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 hidePromptInput: true,\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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",
4
+ "sourcesContent": ["/**\n * Model Command\n *\n * Interactive model configuration using SimpleSelector phase state machine.\n *\n * Phase flow:\n * main \u2192 (select pointer) \u2192 assign \u2192 (select model) \u2192 main\n * main \u2192 (Manage Library) \u2192 library \u2192 (select model) \u2192 model-actions\n * \u2193\n * confirm-delete \u2192 library\n * library \u2192 (+ Add New) \u2192 add-model \u2192 library\n */\n\nimport React, { useState, useMemo, useCallback } from 'react'\nimport { SimpleSelector } from '@components/SimpleSelector'\nimport type { SelectorItem, StatusOverlay } from '@components/SimpleSelector'\nimport { ModelSelector } from '@components/ModelSelector'\nimport { enableConfigs } from '@utils/config'\nimport {\n ModelPointerType,\n setModelPointer,\n getGlobalConfig,\n} from '@utils/config'\nimport { getModelManager, reloadModelManager } from '@utils/model'\nimport { triggerModelConfigChange } from '@messages'\nimport { t } from '@i18n'\nimport type { Command } from '@commands'\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype ModelPhase =\n | { type: 'main' }\n | { type: 'assign'; pointer: ModelPointerType }\n | { type: 'library' }\n | { type: 'model-actions'; modelName: string; modelLabel: string }\n | { type: 'confirm-delete'; modelName: string; modelLabel: string }\n | { type: 'add-model' }\n | { type: 'edit-model'; modelName: string; modelLabel: string }\n\n// Special item IDs\nconst ID_MANAGE_LIBRARY = '__manage_library__'\nconst ID_ADD_NEW = '__add_new__'\nconst ID_CLEAR = '__clear__'\nconst ID_EDIT = '__edit__'\nconst ID_DELETE = '__delete__'\nconst ID_BACK = '__back__'\nconst ID_CONFIRM_YES = '__yes__'\nconst ID_CONFIRM_NO = '__no__'\n\nconst POINTER_TYPES: ModelPointerType[] = [\n 'main',\n 'task',\n 'reasoning',\n 'quick',\n 'compact',\n]\n\nconst POINTER_LABELS: Record<ModelPointerType, string> = {\n main: 'Main',\n task: 'Task',\n reasoning: 'Reasoning',\n quick: 'Quick',\n compact: 'Compact',\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction getPointerDescription(pointer: ModelPointerType): string {\n const key = `ui.modelConfig.${pointer}Description` as const\n return t(key)\n}\n\n// =============================================================================\n// Main Component\n// =============================================================================\n\ntype Props = {\n onClose: () => void\n abortController?: AbortController\n}\n\nfunction ModelCommand({ onClose, abortController }: Props): React.ReactNode {\n const [phase, setPhase] = useState<ModelPhase>({ type: 'main' })\n const [statusOverlay, setStatusOverlay] = useState<StatusOverlay | null>(null)\n const [refreshKey, setRefreshKey] = useState(0)\n\n // Reload models and trigger config change\n const refreshModels = useCallback(() => {\n reloadModelManager()\n triggerModelConfigChange()\n setRefreshKey(prev => prev + 1)\n }, [])\n\n // Show a temporary success overlay then transition\n const showSuccessAndGo = useCallback(\n (message: string, nextPhase: ModelPhase) => {\n setStatusOverlay({ type: 'success', message })\n setTimeout(() => {\n setStatusOverlay(null)\n setPhase(nextPhase)\n }, 800)\n },\n [],\n )\n\n // \u2500\u2500\u2500 Phase: main \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 if (phase.type === 'main') {\n return (\n <MainPhase\n refreshKey={refreshKey}\n statusOverlay={statusOverlay}\n onSelectPointer={pointer => setPhase({ type: 'assign', pointer })}\n onManageLibrary={() => setPhase({ type: 'library' })}\n onClose={onClose}\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: assign \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 if (phase.type === 'assign') {\n return (\n <AssignPhase\n pointer={phase.pointer}\n refreshKey={refreshKey}\n statusOverlay={statusOverlay}\n onAssign={(pointer, modelName) => {\n setModelPointer(pointer, modelName)\n refreshModels()\n showSuccessAndGo(\n t('commands.model.pointerUpdated').replace(\n '{pointer}',\n POINTER_LABELS[pointer],\n ),\n { type: 'main' },\n )\n }}\n onClear={pointer => {\n setModelPointer(pointer, '')\n refreshModels()\n showSuccessAndGo(\n t('commands.model.pointerCleared').replace(\n '{pointer}',\n POINTER_LABELS[pointer],\n ),\n { type: 'main' },\n )\n }}\n onClose={() => setPhase({ type: 'main' })}\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: library \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 if (phase.type === 'library') {\n return (\n <LibraryPhase\n refreshKey={refreshKey}\n statusOverlay={statusOverlay}\n onSelectModel={(modelName, modelLabel) =>\n setPhase({ type: 'model-actions', modelName, modelLabel })\n }\n onAddNew={() => {\n enableConfigs()\n abortController?.abort?.()\n setPhase({ type: 'add-model' })\n }}\n onClose={() => setPhase({ type: 'main' })}\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: model-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\n if (phase.type === 'model-actions') {\n return (\n <ModelActionsPhase\n modelName={phase.modelName}\n modelLabel={phase.modelLabel}\n onEdit={() => {\n enableConfigs()\n abortController?.abort?.()\n setPhase({\n type: 'edit-model',\n modelName: phase.modelName,\n modelLabel: phase.modelLabel,\n })\n }}\n onDelete={() =>\n setPhase({\n type: 'confirm-delete',\n modelName: phase.modelName,\n modelLabel: phase.modelLabel,\n })\n }\n onClose={() => setPhase({ type: 'library' })}\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: confirm-delete \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 if (phase.type === 'confirm-delete') {\n return (\n <ConfirmDeletePhase\n modelName={phase.modelName}\n modelLabel={phase.modelLabel}\n statusOverlay={statusOverlay}\n onConfirm={() => {\n try {\n const modelManager = getModelManager()\n modelManager.removeModel(phase.modelName)\n refreshModels()\n showSuccessAndGo(t('commands.model.modelDeleted'), {\n type: 'library',\n })\n } catch {\n setStatusOverlay({\n type: 'error',\n message: t('commands.model.deleteFailed'),\n })\n setTimeout(() => {\n setStatusOverlay(null)\n setPhase({\n type: 'model-actions',\n modelName: phase.modelName,\n modelLabel: phase.modelLabel,\n })\n }, 1500)\n }\n }}\n onCancel={() =>\n setPhase({\n type: 'model-actions',\n modelName: phase.modelName,\n modelLabel: phase.modelLabel,\n })\n }\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: add-model \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 if (phase.type === 'add-model') {\n return (\n <ModelSelector\n onDone={() => {\n refreshModels()\n setPhase({ type: 'library' })\n }}\n onCancel={() => setPhase({ type: 'library' })}\n skipModelType={true}\n isOnboarding={false}\n abortController={new AbortController()}\n />\n )\n }\n\n // \u2500\u2500\u2500 Phase: edit-model \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 if (phase.type === 'edit-model') {\n const modelManager = getModelManager()\n const profile = modelManager\n .getAvailableModels()\n .find(m => m.modelName === phase.modelName)\n if (!profile) {\n // Model not found, go back to library\n setPhase({ type: 'library' })\n return null\n }\n return (\n <ModelSelector\n onDone={() => {\n refreshModels()\n setPhase({ type: 'library' })\n }}\n onCancel={() =>\n setPhase({\n type: 'model-actions',\n modelName: phase.modelName,\n modelLabel: phase.modelLabel,\n })\n }\n skipModelType={true}\n isOnboarding={false}\n abortController={new AbortController()}\n editingModel={profile}\n />\n )\n }\n\n // Fallback (shouldn't happen)\n return null\n}\n\n// =============================================================================\n// Phase Components\n// =============================================================================\n\nfunction MainPhase({\n refreshKey,\n statusOverlay,\n onSelectPointer,\n onManageLibrary,\n onClose,\n}: {\n refreshKey: number\n statusOverlay: StatusOverlay | null\n onSelectPointer: (pointer: ModelPointerType) => void\n onManageLibrary: () => void\n onClose: () => void\n}) {\n const items = useMemo((): SelectorItem[] => {\n const config = getGlobalConfig()\n const modelManager = getModelManager()\n const models = modelManager.getAvailableModels()\n\n const pointerItems: SelectorItem[] = POINTER_TYPES.map(pointer => {\n const assignedModelName = config.modelPointers?.[pointer] || ''\n const model = models.find(m => m.modelName === assignedModelName)\n const description = model\n ? `${model.name} (${model.provider})`\n : getPointerDescription(pointer)\n\n return {\n id: pointer,\n label: POINTER_LABELS[pointer],\n description,\n category: t('commands.model.pointersCategory'),\n statusIcon: model ? '\\u2713' : undefined,\n statusColor: model ? '#4EBA65' : undefined,\n }\n })\n\n const actionItems: SelectorItem[] = [\n {\n id: ID_MANAGE_LIBRARY,\n label: t('commands.model.modelLibrary'),\n description: t('commands.model.modelLibrarySubtitle'),\n category: t('commands.model.actionsCategory'),\n },\n ]\n\n return [...pointerItems, ...actionItems]\n }, [refreshKey])\n\n const handleSelect = useCallback(\n (item: SelectorItem) => {\n if (item.id === ID_MANAGE_LIBRARY) {\n onManageLibrary()\n } else {\n onSelectPointer(item.id as ModelPointerType)\n }\n },\n [onSelectPointer, onManageLibrary],\n )\n\n return (\n <SimpleSelector\n title={t('commands.model.title')}\n items={items}\n onSelect={handleSelect}\n onClose={onClose}\n groupByCategory={true}\n statusOverlay={statusOverlay}\n />\n )\n}\n\nfunction AssignPhase({\n pointer,\n refreshKey,\n statusOverlay,\n onAssign,\n onClear,\n onClose,\n}: {\n pointer: ModelPointerType\n refreshKey: number\n statusOverlay: StatusOverlay | null\n onAssign: (pointer: ModelPointerType, modelName: string) => void\n onClear: (pointer: ModelPointerType) => void\n onClose: () => void\n}) {\n const items = useMemo((): SelectorItem[] => {\n const config = getGlobalConfig()\n const modelManager = getModelManager()\n const models = modelManager.getAvailableModels()\n const currentAssignment = config.modelPointers?.[pointer] || ''\n\n const modelItems: SelectorItem[] = models.map(model => ({\n id: model.modelName,\n label: model.name,\n description: `${model.provider}: ${model.modelName}`,\n isCurrent: model.modelName === currentAssignment,\n }))\n\n // Add \"Clear Assignment\" option if there's a current assignment\n if (currentAssignment) {\n modelItems.push({\n id: ID_CLEAR,\n label: t('commands.model.clearAssignment'),\n statusIcon: '\\u2715',\n statusColor: '#FF6B80',\n })\n }\n\n return modelItems\n }, [pointer, refreshKey])\n\n const handleSelect = useCallback(\n (item: SelectorItem) => {\n if (item.id === ID_CLEAR) {\n onClear(pointer)\n } else {\n onAssign(pointer, item.id)\n }\n },\n [pointer, onAssign, onClear],\n )\n\n return (\n <SimpleSelector\n title={t('commands.model.selectModel').replace(\n '{pointer}',\n POINTER_LABELS[pointer],\n )}\n items={items}\n onSelect={handleSelect}\n onClose={onClose}\n statusOverlay={statusOverlay}\n />\n )\n}\n\nfunction LibraryPhase({\n refreshKey,\n statusOverlay,\n onSelectModel,\n onAddNew,\n onClose,\n}: {\n refreshKey: number\n statusOverlay: StatusOverlay | null\n onSelectModel: (modelName: string, modelLabel: string) => void\n onAddNew: () => void\n onClose: () => void\n}) {\n const items = useMemo((): SelectorItem[] => {\n const config = getGlobalConfig()\n const modelManager = getModelManager()\n const models = modelManager.getAvailableModels()\n\n const modelItems: SelectorItem[] = models.map(model => {\n // Find which pointers use this model\n const usedBy: string[] = []\n POINTER_TYPES.forEach(p => {\n if (config.modelPointers?.[p] === model.modelName) {\n usedBy.push(POINTER_LABELS[p])\n }\n })\n const usageDesc = usedBy.length > 0 ? `[${usedBy.join(', ')}]` : ''\n\n return {\n id: model.modelName,\n label: model.name,\n description: `${model.provider}${usageDesc ? ' ' + usageDesc : ''}`,\n statusIcon: usedBy.length > 0 ? '\\u2713' : undefined,\n statusColor: usedBy.length > 0 ? '#4EBA65' : undefined,\n data: { modelLabel: model.name },\n }\n })\n\n modelItems.push({\n id: ID_ADD_NEW,\n label: t('commands.model.addNewModel'),\n })\n\n return modelItems\n }, [refreshKey])\n\n const handleSelect = useCallback(\n (item: SelectorItem) => {\n if (item.id === ID_ADD_NEW) {\n onAddNew()\n } else {\n const data = item.data as { modelLabel: string } | undefined\n onSelectModel(item.id, data?.modelLabel || item.label)\n }\n },\n [onSelectModel, onAddNew],\n )\n\n return (\n <SimpleSelector\n title={t('commands.model.modelLibrary')}\n subtitle={t('commands.model.modelLibrarySubtitle')}\n items={items}\n onSelect={handleSelect}\n onClose={onClose}\n statusOverlay={statusOverlay}\n />\n )\n}\n\nfunction ModelActionsPhase({\n modelName,\n modelLabel,\n onEdit,\n onDelete,\n onClose,\n}: {\n modelName: string\n modelLabel: string\n onEdit: () => void\n onDelete: () => void\n onClose: () => void\n}) {\n const items: SelectorItem[] = [\n {\n id: ID_EDIT,\n label: t('commands.model.editModel'),\n },\n {\n id: ID_DELETE,\n label: t('common.delete'),\n statusIcon: '\\u2715',\n statusColor: '#FF6B80',\n },\n {\n id: ID_BACK,\n label: t('common.back'),\n },\n ]\n\n const handleSelect = useCallback(\n (item: SelectorItem) => {\n if (item.id === ID_EDIT) {\n onEdit()\n } else if (item.id === ID_DELETE) {\n onDelete()\n } else {\n onClose()\n }\n },\n [onEdit, onDelete, onClose],\n )\n\n return (\n <SimpleSelector\n title={t('commands.model.modelActions').replace('{model}', modelLabel)}\n items={items}\n onSelect={handleSelect}\n onClose={onClose}\n />\n )\n}\n\nfunction ConfirmDeletePhase({\n modelName,\n modelLabel,\n statusOverlay,\n onConfirm,\n onCancel,\n}: {\n modelName: string\n modelLabel: string\n statusOverlay: StatusOverlay | null\n onConfirm: () => void\n onCancel: () => void\n}) {\n const items: SelectorItem[] = [\n {\n id: ID_CONFIRM_YES,\n label: t('commands.model.confirmDeleteYes'),\n statusIcon: '\\u2715',\n statusColor: '#FF6B80',\n },\n {\n id: ID_CONFIRM_NO,\n label: t('commands.model.confirmDeleteNo'),\n },\n ]\n\n const handleSelect = useCallback(\n (item: SelectorItem) => {\n if (item.id === ID_CONFIRM_YES) {\n onConfirm()\n } else {\n onCancel()\n }\n },\n [onConfirm, onCancel],\n )\n\n return (\n <SimpleSelector\n title={t('commands.model.confirmDeleteTitle').replace(\n '{model}',\n modelLabel,\n )}\n items={items}\n onSelect={handleSelect}\n onClose={onCancel}\n statusOverlay={statusOverlay}\n />\n )\n}\n\n// =============================================================================\n// Command Export\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 hidePromptInput: true,\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
6
  "names": ["model"]
7
7
  }