dexto 1.5.5 → 1.5.7

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 (234) hide show
  1. package/README.md +13 -0
  2. package/dist/agents/agent-template.yml +1 -1
  3. package/dist/agents/coding-agent/coding-agent.yml +17 -2
  4. package/dist/agents/coding-agent/skills/code-review.md +46 -0
  5. package/dist/agents/explore-agent/explore-agent.yml +2 -0
  6. package/dist/agents/podcast-agent/podcast-agent.yml +1 -1
  7. package/dist/analytics/events.d.ts +1 -1
  8. package/dist/analytics/events.d.ts.map +1 -1
  9. package/dist/api/server-hono.d.ts.map +1 -1
  10. package/dist/api/server-hono.js +55 -10
  11. package/dist/cli/assets/dexto-logo.svg +31 -0
  12. package/dist/cli/auth/api-client.d.ts +49 -0
  13. package/dist/cli/auth/api-client.d.ts.map +1 -0
  14. package/dist/cli/auth/api-client.js +127 -0
  15. package/dist/cli/auth/constants.d.ts +23 -0
  16. package/dist/cli/auth/constants.d.ts.map +1 -0
  17. package/dist/cli/auth/constants.js +24 -0
  18. package/dist/cli/auth/index.d.ts +5 -0
  19. package/dist/cli/auth/index.d.ts.map +1 -0
  20. package/dist/cli/auth/index.js +6 -0
  21. package/dist/cli/auth/oauth.d.ts +26 -0
  22. package/dist/cli/auth/oauth.d.ts.map +1 -0
  23. package/dist/cli/auth/oauth.js +327 -0
  24. package/dist/cli/auth/service.d.ts +20 -0
  25. package/dist/cli/auth/service.d.ts.map +1 -0
  26. package/dist/cli/auth/service.js +147 -0
  27. package/dist/cli/commands/auth/index.d.ts +4 -0
  28. package/dist/cli/commands/auth/index.d.ts.map +1 -0
  29. package/dist/cli/commands/auth/index.js +4 -0
  30. package/dist/cli/commands/auth/login.d.ts +9 -0
  31. package/dist/cli/commands/auth/login.d.ts.map +1 -0
  32. package/dist/cli/commands/auth/login.js +255 -0
  33. package/dist/cli/commands/auth/logout.d.ts +5 -0
  34. package/dist/cli/commands/auth/logout.d.ts.map +1 -0
  35. package/dist/cli/commands/auth/logout.js +51 -0
  36. package/dist/cli/commands/auth/status.d.ts +2 -0
  37. package/dist/cli/commands/auth/status.d.ts.map +1 -0
  38. package/dist/cli/commands/auth/status.js +22 -0
  39. package/dist/cli/commands/billing/index.d.ts +2 -0
  40. package/dist/cli/commands/billing/index.d.ts.map +1 -0
  41. package/dist/cli/commands/billing/index.js +2 -0
  42. package/dist/cli/commands/billing/status.d.ts +6 -0
  43. package/dist/cli/commands/billing/status.d.ts.map +1 -0
  44. package/dist/cli/commands/billing/status.js +60 -0
  45. package/dist/cli/commands/index.d.ts +4 -0
  46. package/dist/cli/commands/index.d.ts.map +1 -1
  47. package/dist/cli/commands/index.js +9 -0
  48. package/dist/cli/commands/interactive-commands/auth/index.d.ts +12 -0
  49. package/dist/cli/commands/interactive-commands/auth/index.d.ts.map +1 -0
  50. package/dist/cli/commands/interactive-commands/auth/index.js +20 -0
  51. package/dist/cli/commands/interactive-commands/command-parser.d.ts +5 -0
  52. package/dist/cli/commands/interactive-commands/command-parser.d.ts.map +1 -1
  53. package/dist/cli/commands/interactive-commands/command-parser.js +6 -0
  54. package/dist/cli/commands/interactive-commands/commands.d.ts +1 -0
  55. package/dist/cli/commands/interactive-commands/commands.d.ts.map +1 -1
  56. package/dist/cli/commands/interactive-commands/commands.js +10 -0
  57. package/dist/cli/commands/interactive-commands/export/index.d.ts +13 -0
  58. package/dist/cli/commands/interactive-commands/export/index.d.ts.map +1 -0
  59. package/dist/cli/commands/interactive-commands/export/index.js +21 -0
  60. package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
  61. package/dist/cli/commands/interactive-commands/general-commands.js +1 -0
  62. package/dist/cli/commands/interactive-commands/mcp/index.d.ts +2 -2
  63. package/dist/cli/commands/interactive-commands/mcp/index.d.ts.map +1 -1
  64. package/dist/cli/commands/interactive-commands/mcp/index.js +4 -7
  65. package/dist/cli/commands/interactive-commands/model/index.d.ts +2 -2
  66. package/dist/cli/commands/interactive-commands/model/index.d.ts.map +1 -1
  67. package/dist/cli/commands/interactive-commands/model/index.js +4 -7
  68. package/dist/cli/commands/interactive-commands/plugin/index.d.ts +13 -0
  69. package/dist/cli/commands/interactive-commands/plugin/index.d.ts.map +1 -0
  70. package/dist/cli/commands/interactive-commands/plugin/index.js +18 -0
  71. package/dist/cli/commands/interactive-commands/prompt-commands.d.ts +3 -1
  72. package/dist/cli/commands/interactive-commands/prompt-commands.d.ts.map +1 -1
  73. package/dist/cli/commands/interactive-commands/prompt-commands.js +72 -36
  74. package/dist/cli/commands/interactive-commands/system/system-commands.d.ts.map +1 -1
  75. package/dist/cli/commands/interactive-commands/system/system-commands.js +2 -3
  76. package/dist/cli/commands/plugin.d.ts +161 -0
  77. package/dist/cli/commands/plugin.d.ts.map +1 -0
  78. package/dist/cli/commands/plugin.js +376 -0
  79. package/dist/cli/commands/setup.d.ts +9 -9
  80. package/dist/cli/commands/setup.d.ts.map +1 -1
  81. package/dist/cli/commands/setup.js +325 -37
  82. package/dist/cli/commands/sync-agents.d.ts +44 -0
  83. package/dist/cli/commands/sync-agents.d.ts.map +1 -0
  84. package/dist/cli/commands/sync-agents.js +483 -0
  85. package/dist/cli/ink-cli/InkCLIRefactored.d.ts +14 -1
  86. package/dist/cli/ink-cli/InkCLIRefactored.d.ts.map +1 -1
  87. package/dist/cli/ink-cli/InkCLIRefactored.js +8 -2
  88. package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts +1 -1
  89. package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts.map +1 -1
  90. package/dist/cli/ink-cli/components/ApprovalPrompt.js +80 -12
  91. package/dist/cli/ink-cli/components/Footer.d.ts +2 -1
  92. package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -1
  93. package/dist/cli/ink-cli/components/Footer.js +6 -2
  94. package/dist/cli/ink-cli/components/SlashCommandAutocomplete.d.ts.map +1 -1
  95. package/dist/cli/ink-cli/components/SlashCommandAutocomplete.js +15 -7
  96. package/dist/cli/ink-cli/components/StatusBar.d.ts +9 -1
  97. package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
  98. package/dist/cli/ink-cli/components/StatusBar.js +17 -5
  99. package/dist/cli/ink-cli/components/TodoPanel.d.ts +11 -8
  100. package/dist/cli/ink-cli/components/TodoPanel.d.ts.map +1 -1
  101. package/dist/cli/ink-cli/components/TodoPanel.js +38 -36
  102. package/dist/cli/ink-cli/components/chat/Header.d.ts.map +1 -1
  103. package/dist/cli/ink-cli/components/chat/Header.js +1 -1
  104. package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
  105. package/dist/cli/ink-cli/components/chat/MessageItem.js +14 -1
  106. package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.js +1 -1
  107. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -1
  108. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +16 -4
  109. package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
  110. package/dist/cli/ink-cli/components/modes/StaticCLI.js +4 -1
  111. package/dist/cli/ink-cli/components/overlays/ExportWizard.d.ts +22 -0
  112. package/dist/cli/ink-cli/components/overlays/ExportWizard.d.ts.map +1 -0
  113. package/dist/cli/ink-cli/components/overlays/ExportWizard.js +308 -0
  114. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.d.ts +1 -0
  115. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.d.ts.map +1 -1
  116. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.js +31 -20
  117. package/dist/cli/ink-cli/components/overlays/MarketplaceAddPrompt.d.ts +20 -0
  118. package/dist/cli/ink-cli/components/overlays/MarketplaceAddPrompt.d.ts.map +1 -0
  119. package/dist/cli/ink-cli/components/overlays/MarketplaceAddPrompt.js +81 -0
  120. package/dist/cli/ink-cli/components/overlays/MarketplaceBrowser.d.ts +31 -0
  121. package/dist/cli/ink-cli/components/overlays/MarketplaceBrowser.d.ts.map +1 -0
  122. package/dist/cli/ink-cli/components/overlays/MarketplaceBrowser.js +297 -0
  123. package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.d.ts.map +1 -1
  124. package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.js +7 -1
  125. package/dist/cli/ink-cli/components/overlays/McpServerActions.d.ts +1 -1
  126. package/dist/cli/ink-cli/components/overlays/McpServerActions.d.ts.map +1 -1
  127. package/dist/cli/ink-cli/components/overlays/McpServerActions.js +9 -0
  128. package/dist/cli/ink-cli/components/overlays/McpServerList.d.ts.map +1 -1
  129. package/dist/cli/ink-cli/components/overlays/McpServerList.js +9 -2
  130. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts.map +1 -1
  131. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.js +15 -2
  132. package/dist/cli/ink-cli/components/overlays/PluginActions.d.ts +27 -0
  133. package/dist/cli/ink-cli/components/overlays/PluginActions.d.ts.map +1 -0
  134. package/dist/cli/ink-cli/components/overlays/PluginActions.js +66 -0
  135. package/dist/cli/ink-cli/components/overlays/PluginList.d.ts +21 -0
  136. package/dist/cli/ink-cli/components/overlays/PluginList.d.ts.map +1 -0
  137. package/dist/cli/ink-cli/components/overlays/PluginList.js +70 -0
  138. package/dist/cli/ink-cli/components/overlays/PluginManager.d.ts +21 -0
  139. package/dist/cli/ink-cli/components/overlays/PluginManager.d.ts.map +1 -0
  140. package/dist/cli/ink-cli/components/overlays/PluginManager.js +63 -0
  141. package/dist/cli/ink-cli/components/overlays/PromptList.d.ts.map +1 -1
  142. package/dist/cli/ink-cli/components/overlays/PromptList.js +4 -1
  143. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts +2 -1
  144. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts.map +1 -1
  145. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.js +61 -2
  146. package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.d.ts +4 -2
  147. package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.d.ts.map +1 -1
  148. package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.js +4 -4
  149. package/dist/cli/ink-cli/constants/tips.js +2 -2
  150. package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
  151. package/dist/cli/ink-cli/containers/InputContainer.js +31 -3
  152. package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
  153. package/dist/cli/ink-cli/containers/OverlayContainer.js +260 -11
  154. package/dist/cli/ink-cli/hooks/index.d.ts +1 -0
  155. package/dist/cli/ink-cli/hooks/index.d.ts.map +1 -1
  156. package/dist/cli/ink-cli/hooks/index.js +1 -0
  157. package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
  158. package/dist/cli/ink-cli/hooks/useCLIState.js +3 -0
  159. package/dist/cli/ink-cli/hooks/useGitBranch.d.ts +13 -0
  160. package/dist/cli/ink-cli/hooks/useGitBranch.d.ts.map +1 -0
  161. package/dist/cli/ink-cli/hooks/useGitBranch.js +35 -0
  162. package/dist/cli/ink-cli/hooks/useInputOrchestrator.d.ts.map +1 -1
  163. package/dist/cli/ink-cli/hooks/useInputOrchestrator.js +50 -6
  164. package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
  165. package/dist/cli/ink-cli/services/processStream.js +42 -10
  166. package/dist/cli/ink-cli/state/initialState.d.ts.map +1 -1
  167. package/dist/cli/ink-cli/state/initialState.js +3 -0
  168. package/dist/cli/ink-cli/state/types.d.ts +16 -1
  169. package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
  170. package/dist/cli/ink-cli/utils/commandOverlays.d.ts.map +1 -1
  171. package/dist/cli/ink-cli/utils/commandOverlays.js +2 -0
  172. package/dist/cli/ink-cli/utils/messageFormatting.d.ts +14 -1
  173. package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
  174. package/dist/cli/ink-cli/utils/messageFormatting.js +68 -8
  175. package/dist/cli/ink-cli/utils/toolUtils.d.ts +11 -0
  176. package/dist/cli/ink-cli/utils/toolUtils.d.ts.map +1 -1
  177. package/dist/cli/ink-cli/utils/toolUtils.js +17 -0
  178. package/dist/cli/mcp/index.d.ts +8 -0
  179. package/dist/cli/mcp/index.d.ts.map +1 -0
  180. package/dist/cli/mcp/index.js +7 -0
  181. package/dist/cli/mcp/oauth-factory.d.ts +6 -0
  182. package/dist/cli/mcp/oauth-factory.d.ts.map +1 -0
  183. package/dist/cli/mcp/oauth-factory.js +25 -0
  184. package/dist/cli/mcp/oauth-provider.d.ts +10 -0
  185. package/dist/cli/mcp/oauth-provider.d.ts.map +1 -0
  186. package/dist/cli/mcp/oauth-provider.js +77 -0
  187. package/dist/cli/mcp/oauth-redirect.d.ts +3 -0
  188. package/dist/cli/mcp/oauth-redirect.d.ts.map +1 -0
  189. package/dist/cli/mcp/oauth-redirect.js +4 -0
  190. package/dist/cli/mcp/oauth-server.d.ts +2 -0
  191. package/dist/cli/mcp/oauth-server.d.ts.map +1 -0
  192. package/dist/cli/mcp/oauth-server.js +70 -0
  193. package/dist/cli/mcp/oauth-store.d.ts +10 -0
  194. package/dist/cli/mcp/oauth-store.d.ts.map +1 -0
  195. package/dist/cli/mcp/oauth-store.js +27 -0
  196. package/dist/cli/mcp/oauth-ui.d.ts +2 -0
  197. package/dist/cli/mcp/oauth-ui.d.ts.map +1 -0
  198. package/dist/cli/mcp/oauth-ui.js +12 -0
  199. package/dist/cli/mcp/oauth-utils.d.ts +2 -0
  200. package/dist/cli/mcp/oauth-utils.d.ts.map +1 -0
  201. package/dist/cli/mcp/oauth-utils.js +17 -0
  202. package/dist/cli/utils/api-key-setup.d.ts.map +1 -1
  203. package/dist/cli/utils/api-key-setup.js +13 -90
  204. package/dist/cli/utils/api-key-verification.d.ts.map +1 -1
  205. package/dist/cli/utils/api-key-verification.js +36 -0
  206. package/dist/cli/utils/config-validation.d.ts +3 -1
  207. package/dist/cli/utils/config-validation.d.ts.map +1 -1
  208. package/dist/cli/utils/config-validation.js +42 -19
  209. package/dist/cli/utils/dexto-auth-check.d.ts +53 -0
  210. package/dist/cli/utils/dexto-auth-check.d.ts.map +1 -0
  211. package/dist/cli/utils/dexto-auth-check.js +104 -0
  212. package/dist/cli/utils/dexto-setup.d.ts +8 -0
  213. package/dist/cli/utils/dexto-setup.d.ts.map +1 -0
  214. package/dist/cli/utils/dexto-setup.js +17 -0
  215. package/dist/cli/utils/options.d.ts.map +1 -1
  216. package/dist/cli/utils/options.js +5 -1
  217. package/dist/cli/utils/provider-setup.d.ts +4 -0
  218. package/dist/cli/utils/provider-setup.d.ts.map +1 -1
  219. package/dist/cli/utils/provider-setup.js +20 -0
  220. package/dist/cli/utils/version-check.d.ts +45 -0
  221. package/dist/cli/utils/version-check.d.ts.map +1 -0
  222. package/dist/cli/utils/version-check.js +195 -0
  223. package/dist/config/cli-overrides.d.ts +17 -8
  224. package/dist/config/cli-overrides.d.ts.map +1 -1
  225. package/dist/config/cli-overrides.js +36 -22
  226. package/dist/config/effective-llm.d.ts +123 -0
  227. package/dist/config/effective-llm.d.ts.map +1 -0
  228. package/dist/config/effective-llm.js +171 -0
  229. package/dist/index.js +451 -126
  230. package/dist/webui/assets/index-C9JXwpvo.css +1 -0
  231. package/dist/webui/assets/{index-DVQWNLpT.js → index-Dl3mj53P.js} +217 -217
  232. package/dist/webui/index.html +2 -2
  233. package/package.json +9 -8
  234. package/dist/webui/assets/index-BglIVTSG.css +0 -1
@@ -0,0 +1,31 @@
1
+ /**
2
+ * MarketplaceBrowser Component
3
+ * Clean, intuitive marketplace browser with two-level navigation
4
+ */
5
+ import React from 'react';
6
+ import { type MarketplacePlugin } from '@dexto/agent-management';
7
+ import type { Key } from '../../hooks/useInputOrchestrator.js';
8
+ export type MarketplaceBrowserAction = {
9
+ type: 'add-marketplace';
10
+ } | {
11
+ type: 'install-plugin';
12
+ plugin: MarketplacePlugin;
13
+ } | {
14
+ type: 'plugin-installed';
15
+ pluginName: string;
16
+ marketplace: string;
17
+ } | {
18
+ type: 'marketplace-added';
19
+ marketplaceName: string;
20
+ };
21
+ interface MarketplaceBrowserProps {
22
+ isVisible: boolean;
23
+ onAction: (action: MarketplaceBrowserAction) => void;
24
+ onClose: () => void;
25
+ }
26
+ export interface MarketplaceBrowserHandle {
27
+ handleInput: (input: string, key: Key) => boolean;
28
+ }
29
+ declare const MarketplaceBrowser: React.ForwardRefExoticComponent<MarketplaceBrowserProps & React.RefAttributes<MarketplaceBrowserHandle>>;
30
+ export default MarketplaceBrowser;
31
+ //# sourceMappingURL=MarketplaceBrowser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarketplaceBrowser.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/MarketplaceBrowser.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,EAQH,KAAK,iBAAiB,EACzB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAG/D,MAAM,MAAM,wBAAwB,GAC9B;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,UAAU,uBAAuB;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,CAAC;IACrD,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACrC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AA0ED,QAAA,MAAM,kBAAkB,0GAsbvB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,297 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * MarketplaceBrowser Component
4
+ * Clean, intuitive marketplace browser with two-level navigation
5
+ */
6
+ import { useState, useEffect, forwardRef, useRef, useImperativeHandle, useMemo, } from 'react';
7
+ import { Box, Text } from 'ink';
8
+ import { listMarketplaces, listAllMarketplacePlugins, installPluginFromMarketplace, getUninstalledDefaults, addMarketplace, listInstalledPlugins, } from '@dexto/agent-management';
9
+ import { logger } from '@dexto/core';
10
+ import { BaseSelector } from '../base/BaseSelector.js';
11
+ /**
12
+ * Get source type icon
13
+ */
14
+ function getSourceIcon(type) {
15
+ switch (type) {
16
+ case 'github':
17
+ return '🐙';
18
+ case 'git':
19
+ return '📦';
20
+ case 'local':
21
+ return '📁';
22
+ default:
23
+ return '📦';
24
+ }
25
+ }
26
+ const MarketplaceBrowser = forwardRef(function MarketplaceBrowser({ isVisible, onAction, onClose }, ref) {
27
+ const baseSelectorRef = useRef(null);
28
+ const [selectedIndex, setSelectedIndex] = useState(0);
29
+ const [isLoading, setIsLoading] = useState(true);
30
+ const [loadError, setLoadError] = useState(null);
31
+ const [view, setView] = useState('marketplaces');
32
+ const [marketplaces, setMarketplaces] = useState([]);
33
+ const [plugins, setPlugins] = useState([]);
34
+ const [selectedMarketplace, setSelectedMarketplace] = useState(null);
35
+ const [isInstalling, setIsInstalling] = useState(false);
36
+ const [uninstalledDefaults, setUninstalledDefaults] = useState([]);
37
+ const [pendingPlugin, setPendingPlugin] = useState(null);
38
+ const [installedPluginNames, setInstalledPluginNames] = useState(new Set());
39
+ // Forward handleInput to BaseSelector
40
+ useImperativeHandle(ref, () => ({
41
+ handleInput: (input, key) => {
42
+ return baseSelectorRef.current?.handleInput(input, key) ?? false;
43
+ },
44
+ }), []);
45
+ // Load data when visible
46
+ useEffect(() => {
47
+ if (isVisible) {
48
+ loadMarketplaces();
49
+ }
50
+ }, [isVisible]);
51
+ // Load marketplaces
52
+ const loadMarketplaces = () => {
53
+ setIsLoading(true);
54
+ setLoadError(null);
55
+ setView('marketplaces');
56
+ setSelectedMarketplace(null);
57
+ setSelectedIndex(0);
58
+ try {
59
+ const mktplaces = listMarketplaces();
60
+ setMarketplaces(mktplaces);
61
+ const allPlugins = listAllMarketplacePlugins();
62
+ setPlugins(allPlugins);
63
+ const defaults = getUninstalledDefaults();
64
+ setUninstalledDefaults(defaults);
65
+ const installed = listInstalledPlugins();
66
+ setInstalledPluginNames(new Set(installed.map((p) => p.name.toLowerCase())));
67
+ }
68
+ catch (error) {
69
+ setLoadError(`Failed to load: ${error instanceof Error ? error.message : String(error)}`);
70
+ setMarketplaces([]);
71
+ setPlugins([]);
72
+ setUninstalledDefaults([]);
73
+ setInstalledPluginNames(new Set());
74
+ }
75
+ finally {
76
+ setIsLoading(false);
77
+ }
78
+ };
79
+ // Show plugins for a marketplace
80
+ const showMarketplacePlugins = (marketplaceName) => {
81
+ setSelectedMarketplace(marketplaceName);
82
+ setView('plugins');
83
+ setSelectedIndex(0);
84
+ };
85
+ // Go back to marketplace list
86
+ const goBackToMarketplaces = () => {
87
+ setView('marketplaces');
88
+ setSelectedMarketplace(null);
89
+ setSelectedIndex(0);
90
+ };
91
+ // Show scope selection for a plugin
92
+ const showScopeSelection = (plugin) => {
93
+ setPendingPlugin(plugin);
94
+ setView('scope-select');
95
+ setSelectedIndex(0);
96
+ };
97
+ // Go back to plugins from scope selection
98
+ const goBackToPlugins = () => {
99
+ setPendingPlugin(null);
100
+ setView('plugins');
101
+ setSelectedIndex(0);
102
+ };
103
+ // Build items based on current view
104
+ const items = useMemo(() => {
105
+ if (view === 'marketplaces') {
106
+ const list = [];
107
+ // Back option first
108
+ list.push({ type: 'back' });
109
+ // Uninstalled default marketplaces (setup prompts)
110
+ for (const def of uninstalledDefaults) {
111
+ list.push({
112
+ type: 'default-marketplace',
113
+ name: def.name,
114
+ sourceValue: def.source.value,
115
+ sourceType: def.source.type,
116
+ });
117
+ }
118
+ // Installed marketplaces
119
+ for (const m of marketplaces) {
120
+ const pluginCount = plugins.filter((p) => p.marketplace === m.name).length;
121
+ list.push({
122
+ type: 'marketplace',
123
+ marketplace: m,
124
+ pluginCount,
125
+ });
126
+ }
127
+ // Add marketplace option
128
+ list.push({ type: 'add-new' });
129
+ return list;
130
+ }
131
+ else if (view === 'scope-select') {
132
+ // Scope selection view
133
+ const list = [{ type: 'back' }];
134
+ list.push({
135
+ type: 'scope',
136
+ scope: 'user',
137
+ label: 'Global (user)',
138
+ description: 'Available in all projects',
139
+ icon: '🌐',
140
+ });
141
+ list.push({
142
+ type: 'scope',
143
+ scope: 'project',
144
+ label: 'Project only',
145
+ description: 'Only in current project, can be committed to git',
146
+ icon: '📁',
147
+ });
148
+ return list;
149
+ }
150
+ else {
151
+ // Plugins view
152
+ const filteredPlugins = selectedMarketplace
153
+ ? plugins.filter((p) => p.marketplace === selectedMarketplace)
154
+ : plugins;
155
+ const list = [{ type: 'back' }];
156
+ for (const plugin of filteredPlugins) {
157
+ const isInstalled = installedPluginNames.has(plugin.name.toLowerCase());
158
+ list.push({
159
+ type: 'plugin',
160
+ plugin,
161
+ isInstalled,
162
+ });
163
+ }
164
+ return list;
165
+ }
166
+ }, [
167
+ view,
168
+ marketplaces,
169
+ plugins,
170
+ selectedMarketplace,
171
+ uninstalledDefaults,
172
+ installedPluginNames,
173
+ ]);
174
+ // Format item for display
175
+ const formatItem = (item, isSelected) => {
176
+ // Back option
177
+ if (item.type === 'back') {
178
+ const label = view === 'scope-select'
179
+ ? 'Back to plugins'
180
+ : view === 'plugins'
181
+ ? 'Back to marketplaces'
182
+ : 'Back to menu';
183
+ return (_jsxs(Box, { children: [_jsx(Text, { color: isSelected ? 'cyan' : 'gray', children: isSelected ? '▸ ' : ' ' }), _jsx(Text, { color: "gray", children: "\u2190 " }), _jsx(Text, { color: isSelected ? 'white' : 'gray', children: label })] }));
184
+ }
185
+ // Scope selection option
186
+ if (item.type === 'scope') {
187
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: isSelected ? 'cyan' : 'gray', children: isSelected ? '▸ ' : ' ' }), _jsxs(Text, { children: [item.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'white', bold: isSelected, children: item.label })] }), isSelected && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: "gray", dimColor: true, children: item.description }) }))] }));
188
+ }
189
+ // Add marketplace option
190
+ if (item.type === 'add-new') {
191
+ return (_jsxs(Box, { children: [_jsx(Text, { color: isSelected ? 'cyan' : 'gray', children: isSelected ? '▸ ' : ' ' }), _jsx(Text, { color: isSelected ? 'green' : 'gray', children: "+ " }), _jsx(Text, { color: isSelected ? 'green' : 'gray', children: "Add custom marketplace" })] }));
192
+ }
193
+ // Default (uninstalled) marketplace
194
+ if (item.type === 'default-marketplace') {
195
+ const icon = getSourceIcon(item.sourceType);
196
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: isSelected ? 'cyan' : 'gray', children: isSelected ? '▸ ' : ' ' }), _jsxs(Text, { children: [icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'white', bold: isSelected, children: item.name }), _jsx(Text, { color: "yellow", children: " (not installed)" })] }), isSelected && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: "gray", dimColor: true, children: item.sourceValue }) }))] }));
197
+ }
198
+ // Installed marketplace
199
+ if (item.type === 'marketplace') {
200
+ const m = item.marketplace;
201
+ const icon = getSourceIcon(m.source.type);
202
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: isSelected ? 'cyan' : 'gray', children: isSelected ? '▸ ' : ' ' }), _jsxs(Text, { children: [icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'white', bold: isSelected, children: m.name }), _jsxs(Text, { color: "gray", dimColor: true, children: [' ', "(", item.pluginCount, " plugins)"] })] }), isSelected && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: "gray", dimColor: true, children: m.source.value }) }))] }));
203
+ }
204
+ // Plugin item
205
+ const p = item.plugin;
206
+ const statusBadge = item.isInstalled ? _jsx(Text, { color: "green", children: " \u2713" }) : null;
207
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: isSelected ? 'cyan' : 'gray', children: isSelected ? '▸ ' : ' ' }), _jsx(Text, { color: isSelected ? 'white' : 'gray', children: "\uD83D\uDCE6 " }), _jsx(Text, { color: isSelected ? 'cyan' : 'white', bold: isSelected, children: p.name }), p.version && (_jsxs(Text, { color: "gray", dimColor: true, children: ["@", p.version] })), p.category && (_jsxs(Text, { color: "magenta", dimColor: true, children: [' ', "[", p.category, "]"] })), statusBadge] }), isSelected && p.description && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: "gray", children: p.description }) })), isSelected && item.isInstalled && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: "gray", dimColor: true, children: "Already installed" }) }))] }));
208
+ };
209
+ // Handle selection
210
+ const handleSelect = async (item) => {
211
+ if (item.type === 'back') {
212
+ if (view === 'scope-select') {
213
+ goBackToPlugins();
214
+ }
215
+ else if (view === 'plugins') {
216
+ goBackToMarketplaces();
217
+ }
218
+ else {
219
+ onClose();
220
+ }
221
+ return;
222
+ }
223
+ if (item.type === 'add-new') {
224
+ onAction({ type: 'add-marketplace' });
225
+ return;
226
+ }
227
+ if (item.type === 'default-marketplace' && !isInstalling) {
228
+ setIsInstalling(true);
229
+ try {
230
+ await addMarketplace(item.sourceValue, { name: item.name });
231
+ onAction({ type: 'marketplace-added', marketplaceName: item.name });
232
+ loadMarketplaces();
233
+ }
234
+ catch (error) {
235
+ logger.error(`Failed to add marketplace ${item.name}: ${error instanceof Error ? error.message : String(error)}`);
236
+ }
237
+ finally {
238
+ setIsInstalling(false);
239
+ }
240
+ return;
241
+ }
242
+ if (item.type === 'marketplace') {
243
+ showMarketplacePlugins(item.marketplace.name);
244
+ return;
245
+ }
246
+ // Show scope selection for plugin
247
+ if (item.type === 'plugin' && !item.isInstalled) {
248
+ showScopeSelection(item.plugin);
249
+ return;
250
+ }
251
+ // Install plugin with selected scope
252
+ if (item.type === 'scope' && pendingPlugin && !isInstalling) {
253
+ setIsInstalling(true);
254
+ try {
255
+ const result = await installPluginFromMarketplace(`${pendingPlugin.name}@${pendingPlugin.marketplace}`, { scope: item.scope });
256
+ setInstalledPluginNames((prev) => {
257
+ const next = new Set(prev);
258
+ next.add(result.pluginName.toLowerCase());
259
+ return next;
260
+ });
261
+ onAction({
262
+ type: 'plugin-installed',
263
+ pluginName: result.pluginName,
264
+ marketplace: result.marketplace,
265
+ });
266
+ // Go back to plugins view after successful install
267
+ goBackToPlugins();
268
+ }
269
+ catch (error) {
270
+ logger.error(`Failed to install ${pendingPlugin.name}: ${error instanceof Error ? error.message : String(error)}`);
271
+ }
272
+ finally {
273
+ setIsInstalling(false);
274
+ }
275
+ }
276
+ };
277
+ // Get title based on view
278
+ const getTitle = () => {
279
+ if (view === 'scope-select' && pendingPlugin) {
280
+ return `Install ${pendingPlugin.name} › Choose Scope`;
281
+ }
282
+ if (view === 'plugins' && selectedMarketplace) {
283
+ return `${selectedMarketplace} › Plugins`;
284
+ }
285
+ return 'Marketplace';
286
+ };
287
+ // Get empty message
288
+ const getEmptyMessage = () => {
289
+ if (loadError)
290
+ return loadError;
291
+ if (view === 'plugins')
292
+ return 'No plugins found in this marketplace';
293
+ return 'No marketplaces. Add one to browse plugins.';
294
+ };
295
+ return (_jsx(BaseSelector, { ref: baseSelectorRef, items: items, isVisible: isVisible, isLoading: isLoading || isInstalling, selectedIndex: selectedIndex, onSelectIndex: setSelectedIndex, onSelect: handleSelect, onClose: onClose, formatItem: formatItem, title: getTitle(), borderColor: "green", emptyMessage: getEmptyMessage(), loadingMessage: isInstalling ? 'Installing...' : 'Loading...' }));
296
+ });
297
+ export default MarketplaceBrowser;
@@ -1 +1 @@
1
- {"version":3,"file":"McpRemoveSelector.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpRemoveSelector.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAuE,MAAM,OAAO,CAAC;AAE5F,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAwC,MAAM,aAAa,CAAC;AAGpF,UAAU,sBAAsB;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACpC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED;;GAEG;AACH,QAAA,MAAM,iBAAiB,wGAmHtB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"McpRemoveSelector.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpRemoveSelector.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAuE,MAAM,OAAO,CAAC;AAE5F,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAwC,MAAM,aAAa,CAAC;AAGpF,UAAU,sBAAsB;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACpC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED;;GAEG;AACH,QAAA,MAAM,iBAAiB,wGAyHtB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -44,6 +44,8 @@ const McpRemoveSelector = forwardRef(function McpRemoveSelector({ isVisible, onS
44
44
  return '🔌';
45
45
  case 'disconnected':
46
46
  return '⏸️';
47
+ case 'auth-required':
48
+ return '🔐';
47
49
  case 'error':
48
50
  return '❌';
49
51
  }
@@ -55,6 +57,8 @@ const McpRemoveSelector = forwardRef(function McpRemoveSelector({ isVisible, onS
55
57
  return 'Connected';
56
58
  case 'disconnected':
57
59
  return 'Disabled';
60
+ case 'auth-required':
61
+ return 'Auth required';
58
62
  case 'error':
59
63
  return 'Failed';
60
64
  }
@@ -64,7 +68,9 @@ const McpRemoveSelector = forwardRef(function McpRemoveSelector({ isVisible, onS
64
68
  ? 'green'
65
69
  : server.status === 'disconnected'
66
70
  ? 'gray'
67
- : 'red', children: [' ', "- ", getStatusText(server.status)] }), server.error && (_jsxs(Text, { color: "gray", children: [' ', "(", server.error.slice(0, 30), server.error.length > 30 ? '...' : '', ")"] }))] }));
71
+ : server.status === 'auth-required'
72
+ ? 'yellow'
73
+ : 'red', children: [' ', "- ", getStatusText(server.status)] }), server.error && (_jsxs(Text, { color: "gray", children: [' ', "(", server.error.slice(0, 30), server.error.length > 30 ? '...' : '', ")"] }))] }));
68
74
  // Handle selection
69
75
  const handleSelect = (server) => {
70
76
  onSelect(server.name);
@@ -6,7 +6,7 @@
6
6
  import React from 'react';
7
7
  import type { Key } from '../../hooks/useInputOrchestrator.js';
8
8
  import type { McpServerStatus } from '@dexto/core';
9
- export type McpServerActionType = 'enable' | 'disable' | 'delete' | 'back';
9
+ export type McpServerActionType = 'enable' | 'disable' | 'authenticate' | 'delete' | 'back';
10
10
  export interface McpServerAction {
11
11
  type: McpServerActionType;
12
12
  server: McpServerStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"McpServerActions.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpServerActions.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,MAAM,EAAE,eAAe,CAAC;CAC3B;AAED,UAAU,qBAAqB;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAC5C,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAUD;;GAEG;AACH,QAAA,MAAM,gBAAgB,sGA0GrB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"McpServerActions.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpServerActions.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,SAAS,GAAG,cAAc,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE5F,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,MAAM,EAAE,eAAe,CAAC;CAC3B;AAED,UAAU,qBAAqB;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAC5C,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAUD;;GAEG;AACH,QAAA,MAAM,gBAAgB,sGAoHrB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -49,6 +49,15 @@ const McpServerActions = forwardRef(function McpServerActions({ isVisible, serve
49
49
  color: 'green',
50
50
  });
51
51
  }
52
+ if (server.status === 'auth-required') {
53
+ actions.push({
54
+ id: 'authenticate',
55
+ type: 'authenticate',
56
+ label: 'Authenticate server',
57
+ icon: '🔐',
58
+ color: 'yellow',
59
+ });
60
+ }
52
61
  // Delete option
53
62
  actions.push({
54
63
  id: 'delete',
@@ -1 +1 @@
1
- {"version":3,"file":"McpServerList.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpServerList.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAuB,MAAM,aAAa,CAAC;AAGpF,MAAM,MAAM,mBAAmB,GACzB;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1B,UAAU,kBAAkB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAChD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAoCD;;GAEG;AACH,QAAA,MAAM,aAAa,gGA4HjB,CAAC;AAEH,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"McpServerList.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpServerList.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAuB,MAAM,aAAa,CAAC;AAGpF,MAAM,MAAM,mBAAmB,GACzB;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1B,UAAU,kBAAkB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAChD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAwCD;;GAEG;AACH,QAAA,MAAM,aAAa,gGA+HjB,CAAC;AAEH,eAAe,aAAa,CAAC"}
@@ -16,6 +16,8 @@ function getStatusIcon(status) {
16
16
  return '🟢';
17
17
  case 'disconnected':
18
18
  return '⚪';
19
+ case 'auth-required':
20
+ return '🔐';
19
21
  case 'error':
20
22
  return '🔴';
21
23
  }
@@ -29,6 +31,8 @@ function getStatusText(status) {
29
31
  return 'connected';
30
32
  case 'disconnected':
31
33
  return 'disabled';
34
+ case 'auth-required':
35
+ return 'auth required';
32
36
  case 'error':
33
37
  return 'failed';
34
38
  }
@@ -59,7 +63,8 @@ const McpServerList = forwardRef(function McpServerList({ isVisible, onAction, o
59
63
  const order = {
60
64
  connected: 0,
61
65
  disconnected: 1,
62
- error: 2,
66
+ 'auth-required': 2,
67
+ error: 3,
63
68
  };
64
69
  return order[a.status] - order[b.status];
65
70
  });
@@ -93,7 +98,9 @@ const McpServerList = forwardRef(function McpServerList({ isVisible, onAction, o
93
98
  ? 'green'
94
99
  : server.status === 'disconnected'
95
100
  ? 'gray'
96
- : 'red', children: ["[", statusText, "]"] })] }));
101
+ : server.status === 'auth-required'
102
+ ? 'yellow'
103
+ : 'red', children: ["[", statusText, "]"] })] }));
97
104
  };
98
105
  // Handle selection
99
106
  const handleSelect = (item) => {
@@ -1 +1 @@
1
- {"version":3,"file":"ModelSelectorRefactored.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/ModelSelectorRefactored.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO3D,OAAO,EAIH,KAAK,WAAW,EACnB,MAAM,yBAAyB,CAAC;AAEjC,KAAK,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhF,UAAU,kBAAkB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,CACX,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,eAAe,KAChC,IAAI,CAAC;IACV,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,iBAAiB,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAiDD;;GAEG;AACH,QAAA,MAAM,aAAa,oHA4rBjB,CAAC;AAEH,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"ModelSelectorRefactored.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/ModelSelectorRefactored.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO3D,OAAO,EAKH,KAAK,WAAW,EACnB,MAAM,yBAAyB,CAAC;AAEjC,KAAK,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhF,UAAU,kBAAkB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,CACX,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,eAAe,KAChC,IAAI,CAAC;IACV,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,iBAAiB,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAmDD;;GAEG;AACH,QAAA,MAAM,aAAa,oHAitBjB,CAAC;AAEH,eAAe,aAAa,CAAC"}
@@ -8,7 +8,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
8
8
  import { useState, useEffect, forwardRef, useRef, useImperativeHandle, useMemo, useCallback, } from 'react';
9
9
  import { Box, Text } from 'ink';
10
10
  import { listOllamaModels, DEFAULT_OLLAMA_URL, getLocalModelById, isReasoningCapableModel, } from '@dexto/core';
11
- import { loadCustomModels, deleteCustomModel, getAllInstalledModels, } from '@dexto/agent-management';
11
+ import { loadCustomModels, deleteCustomModel, getAllInstalledModels, isDextoAuthEnabled, } from '@dexto/agent-management';
12
12
  function isAddCustomOption(item) {
13
13
  return 'type' in item && item.type === 'add-custom';
14
14
  }
@@ -134,8 +134,15 @@ const ModelSelector = forwardRef(function ModelSelector({ isVisible, onSelectMod
134
134
  if (provider === 'ollama' || provider === 'local' || provider === 'vertex') {
135
135
  continue;
136
136
  }
137
+ // Skip dexto provider when feature is not enabled
138
+ if (provider === 'dexto' && !isDextoAuthEnabled()) {
139
+ continue;
140
+ }
137
141
  const providerModels = allModels[provider];
138
142
  for (const model of providerModels) {
143
+ // For dexto provider, models have originalProvider field
144
+ // showing which provider the model originally came from
145
+ const originalProvider = 'originalProvider' in model ? model.originalProvider : undefined;
139
146
  modelList.push({
140
147
  provider,
141
148
  name: model.name,
@@ -145,6 +152,8 @@ const ModelSelector = forwardRef(function ModelSelector({ isVisible, onSelectMod
145
152
  isCurrent: provider === currentConfig.provider &&
146
153
  model.name === currentConfig.model,
147
154
  isCustom: false,
155
+ // Store original provider for display purposes
156
+ ...(originalProvider && { originalProvider }),
148
157
  });
149
158
  }
150
159
  }
@@ -504,7 +513,11 @@ const ModelSelector = forwardRef(function ModelSelector({ isVisible, onSelectMod
504
513
  }
505
514
  // Show action buttons for selected custom models
506
515
  const showActions = isSelected && item.isCustom;
507
- return (_jsxs(Box, { paddingX: 0, paddingY: 0, children: [item.isCustom && _jsx(Text, { color: isSelected ? 'orange' : 'gray', children: "\u2605 " }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: item.displayName || item.name }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [" (", item.provider, ")"] }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [' ', "\u2022 ", item.maxInputTokens.toLocaleString(), " tokens"] }), item.isDefault && (_jsx(Text, { color: isSelected ? 'white' : 'gray', children: " [DEFAULT]" })), item.isCurrent && !showActions && (_jsxs(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: [' ', "\u2190 Current"] })), showActions && (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsxs(Text, { color: customModelAction === 'edit' ? 'green' : 'gray', bold: customModelAction === 'edit', inverse: customModelAction === 'edit', children: [' ', "Edit", ' '] }), _jsx(Text, { children: " " }), _jsxs(Text, { color: customModelAction === 'delete' ? 'red' : 'gray', bold: customModelAction === 'delete', inverse: customModelAction === 'delete', children: [' ', "Delete", ' '] })] }))] }, `${item.provider}-${item.name}`));
516
+ // Show original provider for gateway models (e.g., dexto showing openai models)
517
+ const providerDisplay = item.originalProvider
518
+ ? `${item.originalProvider} via ${item.provider}`
519
+ : item.provider;
520
+ return (_jsxs(Box, { paddingX: 0, paddingY: 0, children: [item.isCustom && _jsx(Text, { color: isSelected ? 'orange' : 'gray', children: "\u2605 " }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: item.displayName || item.name }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [" (", providerDisplay, ")"] }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [' ', "\u2022 ", item.maxInputTokens.toLocaleString(), " tokens"] }), item.isDefault && (_jsx(Text, { color: isSelected ? 'white' : 'gray', children: " [DEFAULT]" })), item.isCurrent && !showActions && (_jsxs(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: [' ', "\u2190 Current"] })), showActions && (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsxs(Text, { color: customModelAction === 'edit' ? 'green' : 'gray', bold: customModelAction === 'edit', inverse: customModelAction === 'edit', children: [' ', "Edit", ' '] }), _jsx(Text, { children: " " }), _jsxs(Text, { color: customModelAction === 'delete' ? 'red' : 'gray', bold: customModelAction === 'delete', inverse: customModelAction === 'delete', children: [' ', "Delete", ' '] })] }))] }, `${item.provider}-${item.name}-${item.isCustom ? 'custom' : 'registry'}`));
508
521
  }), filteredItems.length > MAX_VISIBLE_ITEMS && (_jsx(Box, { paddingX: 0, paddingY: 0, children: _jsxs(Text, { color: "gray", children: [scrollOffset > 0 ? '↑ more above' : '', scrollOffset > 0 && scrollOffset + MAX_VISIBLE_ITEMS < filteredItems.length
509
522
  ? ' | '
510
523
  : '', scrollOffset + MAX_VISIBLE_ITEMS < filteredItems.length
@@ -0,0 +1,27 @@
1
+ /**
2
+ * PluginActions Component
3
+ * Clean action menu for a selected plugin
4
+ */
5
+ import React from 'react';
6
+ import type { Key } from '../../hooks/useInputOrchestrator.js';
7
+ import type { ListedPlugin } from '@dexto/agent-management';
8
+ export type PluginActionType = 'uninstall' | 'back';
9
+ export interface PluginActionResult {
10
+ type: PluginActionType;
11
+ plugin: ListedPlugin;
12
+ }
13
+ interface PluginActionsProps {
14
+ isVisible: boolean;
15
+ plugin: ListedPlugin | null;
16
+ onAction: (action: PluginActionResult) => void;
17
+ onClose: () => void;
18
+ }
19
+ export interface PluginActionsHandle {
20
+ handleInput: (input: string, key: Key) => boolean;
21
+ }
22
+ /**
23
+ * Plugin Actions - action menu for a specific plugin
24
+ */
25
+ declare const PluginActions: React.ForwardRefExoticComponent<PluginActionsProps & React.RefAttributes<PluginActionsHandle>>;
26
+ export default PluginActions;
27
+ //# sourceMappingURL=PluginActions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginActions.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/PluginActions.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACxB;AAED,UAAU,kBAAkB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC/C,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAUD;;GAEG;AACH,QAAA,MAAM,aAAa,gGA+FjB,CAAC;AAEH,eAAe,aAAa,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * PluginActions Component
4
+ * Clean action menu for a selected plugin
5
+ */
6
+ import { useState, useEffect, forwardRef, useRef, useImperativeHandle, useMemo, } from 'react';
7
+ import { Box, Text } from 'ink';
8
+ import { BaseSelector } from '../base/BaseSelector.js';
9
+ /**
10
+ * Plugin Actions - action menu for a specific plugin
11
+ */
12
+ const PluginActions = forwardRef(function PluginActions({ isVisible, plugin, onAction, onClose }, ref) {
13
+ const baseSelectorRef = useRef(null);
14
+ const [selectedIndex, setSelectedIndex] = useState(0);
15
+ // Forward handleInput to BaseSelector
16
+ useImperativeHandle(ref, () => ({
17
+ handleInput: (input, key) => {
18
+ return baseSelectorRef.current?.handleInput(input, key) ?? false;
19
+ },
20
+ }), []);
21
+ // Reset selection when becoming visible or plugin changes
22
+ useEffect(() => {
23
+ if (isVisible) {
24
+ setSelectedIndex(0);
25
+ }
26
+ }, [isVisible, plugin]);
27
+ // Build action items
28
+ const items = useMemo(() => {
29
+ if (!plugin)
30
+ return [];
31
+ return [
32
+ {
33
+ id: 'back',
34
+ type: 'back',
35
+ label: 'Back to list',
36
+ icon: '←',
37
+ color: 'gray',
38
+ },
39
+ {
40
+ id: 'uninstall',
41
+ type: 'uninstall',
42
+ label: 'Uninstall',
43
+ icon: '🗑',
44
+ color: 'red',
45
+ },
46
+ ];
47
+ }, [plugin]);
48
+ // Format item for display - clean single line
49
+ const formatItem = (item, isSelected) => {
50
+ const isBack = item.type === 'back';
51
+ return (_jsxs(Box, { children: [_jsx(Text, { color: isSelected ? 'cyan' : 'gray', children: isSelected ? '▸ ' : ' ' }), _jsxs(Text, { color: isBack ? 'gray' : isSelected ? item.color : 'gray', children: [item.icon, " "] }), _jsx(Text, { color: isBack ? (isSelected ? 'white' : 'gray') : isSelected ? item.color : 'white', bold: isSelected && !isBack, children: item.label })] }));
52
+ };
53
+ // Handle selection
54
+ const handleSelect = (item) => {
55
+ if (!plugin)
56
+ return;
57
+ onAction({ type: item.type, plugin });
58
+ };
59
+ if (!plugin)
60
+ return null;
61
+ const version = plugin.version || 'unknown';
62
+ const scopeBadge = plugin.scope ? ` [${plugin.scope}]` : '';
63
+ const title = `📦 ${plugin.name}@${version}${scopeBadge}`;
64
+ return (_jsx(BaseSelector, { ref: baseSelectorRef, items: items, isVisible: isVisible, isLoading: false, selectedIndex: selectedIndex, onSelectIndex: setSelectedIndex, onSelect: handleSelect, onClose: onClose, formatItem: formatItem, title: title, borderColor: "magenta", emptyMessage: "No actions available" }));
65
+ });
66
+ export default PluginActions;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * PluginList Component
3
+ * Clean table-like view of installed plugins
4
+ */
5
+ import React from 'react';
6
+ import { type ListedPlugin } from '@dexto/agent-management';
7
+ import type { Key } from '../../hooks/useInputOrchestrator.js';
8
+ interface PluginListProps {
9
+ isVisible: boolean;
10
+ onPluginSelect: (plugin: ListedPlugin) => void;
11
+ onClose: () => void;
12
+ }
13
+ export interface PluginListHandle {
14
+ handleInput: (input: string, key: Key) => boolean;
15
+ }
16
+ /**
17
+ * Plugin list overlay - shows installed plugins in clean table format
18
+ */
19
+ declare const PluginList: React.ForwardRefExoticComponent<PluginListProps & React.RefAttributes<PluginListHandle>>;
20
+ export default PluginList;
21
+ //# sourceMappingURL=PluginList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginList.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/PluginList.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,EAAwB,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAG/D,UAAU,eAAe;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/C,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC7B,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAaD;;GAEG;AACH,QAAA,MAAM,UAAU,0FA0Hd,CAAC;AAEH,eAAe,UAAU,CAAC"}