dexto 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/README.md +62 -7
  2. package/dist/agents/agent-template.yml +2 -2
  3. package/dist/agents/coding-agent/coding-agent.yml +22 -16
  4. package/dist/agents/database-agent/database-agent.yml +2 -2
  5. package/dist/agents/default-agent.yml +7 -5
  6. package/dist/agents/github-agent/github-agent.yml +2 -2
  7. package/dist/agents/product-name-researcher/product-name-researcher.yml +2 -2
  8. package/dist/agents/talk2pdf-agent/talk2pdf-agent.yml +2 -2
  9. package/dist/analytics/events.d.ts +13 -6
  10. package/dist/analytics/events.d.ts.map +1 -1
  11. package/dist/analytics/index.d.ts +1 -1
  12. package/dist/analytics/index.d.ts.map +1 -1
  13. package/dist/analytics/index.js +6 -2
  14. package/dist/api/server-hono.d.ts.map +1 -1
  15. package/dist/api/server-hono.js +27 -5
  16. package/dist/cli/cli-subscriber.d.ts +4 -0
  17. package/dist/cli/cli-subscriber.d.ts.map +1 -1
  18. package/dist/cli/cli-subscriber.js +40 -2
  19. package/dist/cli/commands/create-app.d.ts +16 -14
  20. package/dist/cli/commands/create-app.d.ts.map +1 -1
  21. package/dist/cli/commands/create-app.js +626 -102
  22. package/dist/cli/commands/create-image.d.ts +7 -0
  23. package/dist/cli/commands/create-image.d.ts.map +1 -0
  24. package/dist/cli/commands/create-image.js +201 -0
  25. package/dist/cli/commands/helpers/formatters.js +7 -7
  26. package/dist/cli/commands/index.d.ts +2 -1
  27. package/dist/cli/commands/index.d.ts.map +1 -1
  28. package/dist/cli/commands/index.js +2 -1
  29. package/dist/cli/commands/init-app.js +7 -7
  30. package/dist/cli/commands/install.d.ts +0 -3
  31. package/dist/cli/commands/install.d.ts.map +1 -1
  32. package/dist/cli/commands/install.js +10 -35
  33. package/dist/cli/commands/interactive-commands/command-parser.js +7 -7
  34. package/dist/cli/commands/interactive-commands/general-commands.js +1 -1
  35. package/dist/cli/commands/interactive-commands/prompt-commands.js +11 -11
  36. package/dist/cli/commands/interactive-commands/system/system-commands.js +3 -3
  37. package/dist/cli/commands/list-agents.js +2 -2
  38. package/dist/cli/commands/session-commands.js +16 -16
  39. package/dist/cli/commands/setup.d.ts +13 -5
  40. package/dist/cli/commands/setup.d.ts.map +1 -1
  41. package/dist/cli/commands/setup.js +860 -65
  42. package/dist/cli/commands/which.js +1 -1
  43. package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts +2 -0
  44. package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts.map +1 -1
  45. package/dist/cli/ink-cli/components/ApprovalPrompt.js +29 -7
  46. package/dist/cli/ink-cli/components/CustomInput.js +1 -1
  47. package/dist/cli/ink-cli/components/EditableMultiLineInput.js +4 -4
  48. package/dist/cli/ink-cli/components/ElicitationForm.d.ts.map +1 -1
  49. package/dist/cli/ink-cli/components/ElicitationForm.js +6 -6
  50. package/dist/cli/ink-cli/components/ErrorBoundary.d.ts.map +1 -1
  51. package/dist/cli/ink-cli/components/ErrorBoundary.js +1 -1
  52. package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -1
  53. package/dist/cli/ink-cli/components/Footer.js +1 -1
  54. package/dist/cli/ink-cli/components/HistorySearchBar.d.ts.map +1 -1
  55. package/dist/cli/ink-cli/components/HistorySearchBar.js +1 -1
  56. package/dist/cli/ink-cli/components/MultiLineInput.d.ts.map +1 -1
  57. package/dist/cli/ink-cli/components/MultiLineInput.js +3 -3
  58. package/dist/cli/ink-cli/components/ResourceAutocomplete.d.ts.map +1 -1
  59. package/dist/cli/ink-cli/components/ResourceAutocomplete.js +4 -4
  60. package/dist/cli/ink-cli/components/SlashCommandAutocomplete.js +3 -3
  61. package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
  62. package/dist/cli/ink-cli/components/StatusBar.js +7 -5
  63. package/dist/cli/ink-cli/components/TextBufferInput.d.ts.map +1 -1
  64. package/dist/cli/ink-cli/components/TextBufferInput.js +6 -6
  65. package/dist/cli/ink-cli/components/base/BaseAutocomplete.js +4 -4
  66. package/dist/cli/ink-cli/components/base/BaseSelector.js +2 -2
  67. package/dist/cli/ink-cli/components/chat/Footer.js +1 -1
  68. package/dist/cli/ink-cli/components/chat/Header.d.ts.map +1 -1
  69. package/dist/cli/ink-cli/components/chat/Header.js +2 -4
  70. package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
  71. package/dist/cli/ink-cli/components/chat/MessageItem.js +5 -5
  72. package/dist/cli/ink-cli/components/chat/MessageList.js +1 -1
  73. package/dist/cli/ink-cli/components/chat/QueuedMessagesDisplay.js +1 -1
  74. package/dist/cli/ink-cli/components/chat/ToolIcon.d.ts +1 -1
  75. package/dist/cli/ink-cli/components/chat/ToolIcon.js +4 -4
  76. package/dist/cli/ink-cli/components/chat/styled-boxes/ConfigBox.js +1 -1
  77. package/dist/cli/ink-cli/components/chat/styled-boxes/HelpBox.js +1 -1
  78. package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.js +2 -2
  79. package/dist/cli/ink-cli/components/chat/styled-boxes/SessionHistoryBox.js +5 -5
  80. package/dist/cli/ink-cli/components/chat/styled-boxes/SessionListBox.js +2 -2
  81. package/dist/cli/ink-cli/components/chat/styled-boxes/ShortcutsBox.js +1 -1
  82. package/dist/cli/ink-cli/components/chat/styled-boxes/StatsBox.js +1 -1
  83. package/dist/cli/ink-cli/components/chat/styled-boxes/StyledBox.js +2 -2
  84. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -1
  85. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +1 -1
  86. package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
  87. package/dist/cli/ink-cli/components/modes/StaticCLI.js +1 -1
  88. package/dist/cli/ink-cli/components/overlays/ApiKeyInput.js +1 -1
  89. package/dist/cli/ink-cli/components/overlays/CustomModelWizard.d.ts +10 -2
  90. package/dist/cli/ink-cli/components/overlays/CustomModelWizard.d.ts.map +1 -1
  91. package/dist/cli/ink-cli/components/overlays/CustomModelWizard.js +198 -89
  92. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.d.ts.map +1 -1
  93. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.js +2 -2
  94. package/dist/cli/ink-cli/components/overlays/McpAddChoice.d.ts.map +1 -1
  95. package/dist/cli/ink-cli/components/overlays/McpAddChoice.js +1 -1
  96. package/dist/cli/ink-cli/components/overlays/McpAddSelector.js +1 -1
  97. package/dist/cli/ink-cli/components/overlays/McpCustomTypeSelector.d.ts.map +1 -1
  98. package/dist/cli/ink-cli/components/overlays/McpCustomTypeSelector.js +2 -2
  99. package/dist/cli/ink-cli/components/overlays/McpCustomWizard.js +1 -1
  100. package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.d.ts.map +1 -1
  101. package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.js +1 -1
  102. package/dist/cli/ink-cli/components/overlays/McpSelector.d.ts.map +1 -1
  103. package/dist/cli/ink-cli/components/overlays/McpSelector.js +1 -1
  104. package/dist/cli/ink-cli/components/overlays/McpServerActions.d.ts.map +1 -1
  105. package/dist/cli/ink-cli/components/overlays/McpServerActions.js +2 -2
  106. package/dist/cli/ink-cli/components/overlays/McpServerList.d.ts.map +1 -1
  107. package/dist/cli/ink-cli/components/overlays/McpServerList.js +1 -1
  108. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts +5 -5
  109. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts.map +1 -1
  110. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.js +222 -68
  111. package/dist/cli/ink-cli/components/overlays/PromptAddChoice.d.ts.map +1 -1
  112. package/dist/cli/ink-cli/components/overlays/PromptAddChoice.js +2 -2
  113. package/dist/cli/ink-cli/components/overlays/PromptAddWizard.js +1 -1
  114. package/dist/cli/ink-cli/components/overlays/PromptDeleteSelector.d.ts.map +1 -1
  115. package/dist/cli/ink-cli/components/overlays/PromptDeleteSelector.js +2 -2
  116. package/dist/cli/ink-cli/components/overlays/PromptList.d.ts.map +1 -1
  117. package/dist/cli/ink-cli/components/overlays/PromptList.js +2 -2
  118. package/dist/cli/ink-cli/components/overlays/SearchOverlay.d.ts.map +1 -1
  119. package/dist/cli/ink-cli/components/overlays/SearchOverlay.js +4 -4
  120. package/dist/cli/ink-cli/components/overlays/SessionSubcommandSelector.d.ts.map +1 -1
  121. package/dist/cli/ink-cli/components/overlays/SessionSubcommandSelector.js +1 -1
  122. package/dist/cli/ink-cli/components/overlays/StreamSelector.d.ts.map +1 -1
  123. package/dist/cli/ink-cli/components/overlays/StreamSelector.js +1 -1
  124. package/dist/cli/ink-cli/components/overlays/ToolBrowser.js +12 -12
  125. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/LocalModelWizard.d.ts +25 -0
  126. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/LocalModelWizard.d.ts.map +1 -0
  127. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/LocalModelWizard.js +609 -0
  128. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/index.d.ts +15 -0
  129. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/index.d.ts.map +1 -0
  130. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/index.js +14 -0
  131. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts +33 -0
  132. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts.map +1 -0
  133. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.js +419 -0
  134. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ApiKeyStep.d.ts +25 -0
  135. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ApiKeyStep.d.ts.map +1 -0
  136. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ApiKeyStep.js +29 -0
  137. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ProviderSelector.d.ts +17 -0
  138. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ProviderSelector.d.ts.map +1 -0
  139. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/ProviderSelector.js +11 -0
  140. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/SetupInfoBanner.d.ts +20 -0
  141. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/SetupInfoBanner.d.ts.map +1 -0
  142. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/SetupInfoBanner.js +10 -0
  143. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/WizardStepInput.d.ts +30 -0
  144. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/WizardStepInput.d.ts.map +1 -0
  145. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/WizardStepInput.js +13 -0
  146. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/index.d.ts +8 -0
  147. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/index.d.ts.map +1 -0
  148. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/shared/index.js +7 -0
  149. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/types.d.ts +79 -0
  150. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/types.d.ts.map +1 -0
  151. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/types.js +38 -0
  152. package/dist/cli/ink-cli/components/renderers/DiffRenderer.js +2 -2
  153. package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.js +1 -1
  154. package/dist/cli/ink-cli/components/renderers/FileRenderer.js +4 -4
  155. package/dist/cli/ink-cli/components/renderers/GenericRenderer.js +2 -2
  156. package/dist/cli/ink-cli/components/renderers/SearchRenderer.js +1 -1
  157. package/dist/cli/ink-cli/components/renderers/ShellRenderer.js +3 -3
  158. package/dist/cli/ink-cli/components/renderers/diff-shared.js +1 -1
  159. package/dist/cli/ink-cli/components/shared/MarkdownText.d.ts.map +1 -1
  160. package/dist/cli/ink-cli/components/shared/MarkdownText.js +8 -6
  161. package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
  162. package/dist/cli/ink-cli/containers/InputContainer.js +23 -1
  163. package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
  164. package/dist/cli/ink-cli/containers/OverlayContainer.js +80 -24
  165. package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts +1 -1
  166. package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts.map +1 -1
  167. package/dist/cli/ink-cli/hooks/useAgentEvents.js +5 -1
  168. package/dist/cli/ink-cli/hooks/useCLIState.d.ts +1 -1
  169. package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
  170. package/dist/cli/ink-cli/hooks/useCLIState.js +4 -2
  171. package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
  172. package/dist/cli/ink-cli/services/processStream.js +77 -9
  173. package/dist/cli/ink-cli/state/types.d.ts +3 -2
  174. package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
  175. package/dist/cli/ink-cli/utils/messageFormatting.d.ts +5 -0
  176. package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
  177. package/dist/cli/ink-cli/utils/messageFormatting.js +59 -1
  178. package/dist/cli/ink-cli/utils/toolUtils.d.ts.map +1 -1
  179. package/dist/cli/ink-cli/utils/toolUtils.js +2 -0
  180. package/dist/cli/utils/api-key-setup.d.ts +54 -4
  181. package/dist/cli/utils/api-key-setup.d.ts.map +1 -1
  182. package/dist/cli/utils/api-key-setup.js +433 -107
  183. package/dist/cli/utils/api-key-verification.d.ts +17 -0
  184. package/dist/cli/utils/api-key-verification.d.ts.map +1 -0
  185. package/dist/cli/utils/api-key-verification.js +211 -0
  186. package/dist/cli/utils/config-validation.d.ts +22 -2
  187. package/dist/cli/utils/config-validation.d.ts.map +1 -1
  188. package/dist/cli/utils/config-validation.js +354 -25
  189. package/dist/cli/utils/local-model-setup.d.ts +46 -0
  190. package/dist/cli/utils/local-model-setup.d.ts.map +1 -0
  191. package/dist/cli/utils/local-model-setup.js +662 -0
  192. package/dist/cli/utils/options.js +1 -1
  193. package/dist/cli/utils/prompt-helpers.d.ts +47 -0
  194. package/dist/cli/utils/prompt-helpers.d.ts.map +1 -0
  195. package/dist/cli/utils/prompt-helpers.js +66 -0
  196. package/dist/cli/utils/provider-setup.d.ts +66 -8
  197. package/dist/cli/utils/provider-setup.d.ts.map +1 -1
  198. package/dist/cli/utils/provider-setup.js +324 -84
  199. package/dist/cli/utils/scaffolding-utils.d.ts +76 -0
  200. package/dist/cli/utils/scaffolding-utils.d.ts.map +1 -0
  201. package/dist/cli/utils/scaffolding-utils.js +246 -0
  202. package/dist/cli/utils/setup-utils.d.ts +16 -0
  203. package/dist/cli/utils/setup-utils.d.ts.map +1 -1
  204. package/dist/cli/utils/setup-utils.js +72 -21
  205. package/dist/cli/utils/template-engine.d.ts +65 -0
  206. package/dist/cli/utils/template-engine.d.ts.map +1 -0
  207. package/dist/cli/utils/template-engine.js +1089 -0
  208. package/dist/config/cli-overrides.d.ts +44 -1
  209. package/dist/config/cli-overrides.d.ts.map +1 -1
  210. package/dist/config/cli-overrides.js +102 -0
  211. package/dist/index.js +315 -53
  212. package/dist/webui/assets/index-8j-KMkX1.js +2054 -0
  213. package/dist/webui/assets/index-c_AX24V4.css +1 -0
  214. package/dist/webui/index.html +3 -9
  215. package/dist/webui/logos/aws-color.svg +1 -0
  216. package/dist/webui/logos/dexto/dexto_logo.svg +1 -1
  217. package/dist/webui/logos/dexto/dexto_logo_light.svg +6 -6
  218. package/dist/webui/logos/glama.svg +7 -0
  219. package/dist/webui/logos/litellm.svg +7 -0
  220. package/dist/webui/logos/openrouter.svg +1 -0
  221. package/package.json +8 -7
  222. package/dist/webui/assets/index-BkwPkZpd.css +0 -1
  223. package/dist/webui/assets/index-D9u1XfyH.js +0 -2025
@@ -1,86 +1,91 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
3
  * CustomModelWizard Component
4
- * Multi-step wizard for adding a custom openai-compatible model
4
+ * Multi-step wizard for adding custom models (openai-compatible, openrouter, litellm, glama, bedrock)
5
+ *
6
+ * Architecture:
7
+ * - Provider configs centralized in ./custom-model-wizard/provider-config.ts
8
+ * - Shared UI components in ./custom-model-wizard/shared/
9
+ * - This file is the orchestrator - handles state, navigation, and keyboard input
5
10
  */
6
- import { useState, useEffect, forwardRef, useImperativeHandle, useCallback } from 'react';
11
+ import { useState, useEffect, forwardRef, useImperativeHandle, useCallback, useRef, } from 'react';
7
12
  import { Box, Text } from 'ink';
8
- import { saveCustomModel } from '@dexto/agent-management';
13
+ import { saveCustomModel, deleteCustomModel, CUSTOM_MODEL_PROVIDERS, saveProviderApiKey, getProviderKeyStatus, resolveApiKeyForProvider, determineApiKeyStorage, } from '@dexto/agent-management';
9
14
  import { logger } from '@dexto/core';
10
- const WIZARD_STEPS = [
11
- {
12
- field: 'name',
13
- label: 'Model Name',
14
- placeholder: 'e.g., llama-3-70b, mixtral-8x7b',
15
- required: true,
16
- validate: (v) => (v.trim() ? null : 'Model name is required'),
17
- },
18
- {
19
- field: 'baseURL',
20
- label: 'API Base URL',
21
- placeholder: 'e.g., http://localhost:11434/v1',
22
- required: true,
23
- validate: (v) => {
24
- if (!v.trim())
25
- return 'Base URL is required';
26
- try {
27
- const url = new URL(v);
28
- if (!['http:', 'https:'].includes(url.protocol)) {
29
- return 'URL must use http:// or https://';
30
- }
31
- return null;
32
- }
33
- catch {
34
- return 'Invalid URL format';
35
- }
36
- },
37
- },
38
- {
39
- field: 'displayName',
40
- label: 'Display Name (optional)',
41
- placeholder: 'e.g., My Local Llama 3',
42
- required: false,
43
- },
44
- {
45
- field: 'maxInputTokens',
46
- label: 'Max Input Tokens (optional)',
47
- placeholder: 'e.g., 128000 (leave blank for default)',
48
- required: false,
49
- validate: (v) => {
50
- if (!v.trim())
51
- return null;
52
- const num = parseInt(v, 10);
53
- if (isNaN(num) || num <= 0)
54
- return 'Must be a positive number';
55
- return null;
56
- },
57
- },
58
- ];
15
+ // Import from new modular architecture
16
+ import { getProviderConfig, getAvailableProviders, runAsyncValidation, } from './custom-model-wizard/provider-config.js';
17
+ import { ProviderSelector, WizardStepInput, SetupInfoBanner, ApiKeyStep, } from './custom-model-wizard/shared/index.js';
18
+ import LocalModelWizard from './custom-model-wizard/LocalModelWizard.js';
59
19
  /**
60
- * Multi-step wizard for custom model configuration
20
+ * Multi-step wizard for custom model configuration.
21
+ * Uses data-driven provider configs instead of scattered conditionals.
61
22
  */
62
- const CustomModelWizard = forwardRef(function CustomModelWizard({ isVisible, onComplete, onClose }, ref) {
23
+ const CustomModelWizard = forwardRef(function CustomModelWizard({ isVisible, onComplete, onClose, initialModel }, ref) {
24
+ // Provider selection (step 0) then wizard steps
25
+ const [selectedProvider, setSelectedProvider] = useState(null);
26
+ const [providerIndex, setProviderIndex] = useState(0);
63
27
  const [currentStep, setCurrentStep] = useState(0);
64
28
  const [values, setValues] = useState({});
65
29
  const [currentInput, setCurrentInput] = useState('');
66
30
  const [error, setError] = useState(null);
67
31
  const [isSaving, setIsSaving] = useState(false);
32
+ const [isValidating, setIsValidating] = useState(false);
33
+ // Track original name when editing (to handle renames)
34
+ const [originalName, setOriginalName] = useState(null);
35
+ const isEditing = initialModel !== null && initialModel !== undefined;
36
+ // Ref for LocalModelWizard (specialized wizard for 'local' provider)
37
+ const localModelWizardRef = useRef(null);
38
+ // Get provider config (data-driven, no conditionals)
39
+ const providerConfig = selectedProvider ? getProviderConfig(selectedProvider) : null;
40
+ const wizardSteps = providerConfig?.steps ?? [];
41
+ const currentStepConfig = wizardSteps[currentStep];
68
42
  // Reset when becoming visible
69
43
  useEffect(() => {
70
44
  if (isVisible) {
45
+ if (initialModel) {
46
+ // Editing mode - pre-populate from initialModel
47
+ const provider = initialModel.provider ?? 'openai-compatible';
48
+ setSelectedProvider(provider);
49
+ setOriginalName(initialModel.name);
50
+ setValues({
51
+ name: initialModel.name,
52
+ baseURL: initialModel.baseURL ?? '',
53
+ displayName: initialModel.displayName ?? '',
54
+ maxInputTokens: initialModel.maxInputTokens?.toString() ?? '',
55
+ apiKey: initialModel.apiKey ?? '',
56
+ });
57
+ setCurrentStep(0);
58
+ setCurrentInput(initialModel.name);
59
+ setProviderIndex(CUSTOM_MODEL_PROVIDERS.indexOf(provider));
60
+ }
61
+ else {
62
+ // Adding mode - reset everything
63
+ setSelectedProvider(null);
64
+ setOriginalName(null);
65
+ setProviderIndex(0);
66
+ setCurrentStep(0);
67
+ setValues({});
68
+ setCurrentInput('');
69
+ }
70
+ setError(null);
71
+ setIsSaving(false);
72
+ setIsValidating(false);
73
+ }
74
+ }, [isVisible, initialModel]);
75
+ const handleProviderSelect = useCallback(() => {
76
+ const provider = CUSTOM_MODEL_PROVIDERS[providerIndex];
77
+ if (provider) {
78
+ setSelectedProvider(provider);
71
79
  setCurrentStep(0);
72
- setValues({});
73
80
  setCurrentInput('');
74
81
  setError(null);
75
- setIsSaving(false);
76
82
  }
77
- }, [isVisible]);
78
- const currentStepConfig = WIZARD_STEPS[currentStep];
83
+ }, [providerIndex]);
79
84
  const handleNext = useCallback(async () => {
80
- if (!currentStepConfig || isSaving)
85
+ if (!currentStepConfig || !selectedProvider || isSaving || isValidating)
81
86
  return;
82
87
  const value = currentInput.trim();
83
- // Validate
88
+ // Sync validation
84
89
  if (currentStepConfig.validate) {
85
90
  const validationError = currentStepConfig.validate(value);
86
91
  if (validationError) {
@@ -92,65 +97,147 @@ const CustomModelWizard = forwardRef(function CustomModelWizard({ isVisible, onC
92
97
  setError(`${currentStepConfig.label} is required`);
93
98
  return;
94
99
  }
100
+ // Async validation (data-driven - no provider-specific conditionals)
101
+ const asyncError = await (async () => {
102
+ setIsValidating(true);
103
+ setError(null);
104
+ try {
105
+ return await runAsyncValidation(selectedProvider, currentStepConfig.field, value);
106
+ }
107
+ finally {
108
+ setIsValidating(false);
109
+ }
110
+ })();
111
+ if (asyncError) {
112
+ setError(asyncError);
113
+ return;
114
+ }
95
115
  // Save value
96
116
  const newValues = { ...values, [currentStepConfig.field]: value };
97
117
  setValues(newValues);
98
118
  setError(null);
99
119
  setCurrentInput('');
100
120
  // Check if we're done
101
- if (currentStep >= WIZARD_STEPS.length - 1) {
102
- // Build model and save
103
- const model = {
104
- name: newValues.name || '',
105
- baseURL: newValues.baseURL || '',
106
- };
107
- if (newValues.displayName?.trim()) {
108
- model.displayName = newValues.displayName.trim();
109
- }
110
- if (newValues.maxInputTokens?.trim()) {
111
- model.maxInputTokens = parseInt(newValues.maxInputTokens, 10);
112
- }
113
- // Save to storage
114
- setIsSaving(true);
121
+ if (currentStep >= wizardSteps.length - 1) {
122
+ await saveModel(newValues);
123
+ }
124
+ else {
125
+ const nextStep = currentStep + 1;
126
+ setCurrentStep(nextStep);
127
+ // Pre-populate next step from stored values (for edit mode)
128
+ const nextStepConfig = wizardSteps[nextStep];
129
+ const nextValue = nextStepConfig ? newValues[nextStepConfig.field] : undefined;
130
+ setCurrentInput(nextValue ?? '');
131
+ }
132
+ }, [
133
+ currentInput,
134
+ currentStep,
135
+ currentStepConfig,
136
+ isSaving,
137
+ isValidating,
138
+ selectedProvider,
139
+ values,
140
+ wizardSteps,
141
+ ]);
142
+ /**
143
+ * Build and save the model using provider config's buildModel function.
144
+ */
145
+ const saveModel = useCallback(async (finalValues) => {
146
+ if (!selectedProvider || !providerConfig)
147
+ return;
148
+ // Build model using provider config (no conditionals!)
149
+ const model = providerConfig.buildModel(finalValues, selectedProvider);
150
+ // Handle API key storage
151
+ const userEnteredKey = finalValues.apiKey?.trim();
152
+ const providerKeyStatus = getProviderKeyStatus(selectedProvider);
153
+ const existingProviderKey = resolveApiKeyForProvider(selectedProvider);
154
+ const keyStorage = determineApiKeyStorage(selectedProvider, userEnteredKey, providerKeyStatus.hasApiKey, existingProviderKey);
155
+ if (keyStorage.saveToProviderEnvVar && userEnteredKey) {
115
156
  try {
116
- await saveCustomModel(model);
117
- onComplete(model);
157
+ await saveProviderApiKey(selectedProvider, userEnteredKey, process.cwd());
118
158
  }
119
159
  catch (err) {
120
- logger.error(`Failed to save custom model: ${err instanceof Error ? err.message : 'Unknown error'}`);
121
- setError(`Failed to save: ${err instanceof Error ? err.message : 'Unknown error'}`);
122
- setIsSaving(false);
160
+ logger.warn(`Failed to save provider API key: ${err instanceof Error ? err.message : 'Unknown error'}`);
161
+ // Fall back to per-model storage
162
+ keyStorage.saveAsPerModel = true;
123
163
  }
124
164
  }
125
- else {
126
- setCurrentStep(currentStep + 1);
165
+ if (keyStorage.saveAsPerModel && userEnteredKey) {
166
+ model.apiKey = userEnteredKey;
127
167
  }
128
- }, [currentInput, currentStep, currentStepConfig, isSaving, onComplete, values]);
168
+ // Save to storage
169
+ setIsSaving(true);
170
+ try {
171
+ // If editing and name changed, delete the old model first
172
+ if (originalName && originalName !== model.name) {
173
+ try {
174
+ await deleteCustomModel(originalName);
175
+ }
176
+ catch (err) {
177
+ // Log but continue - old model might already be deleted
178
+ logger.warn(`Failed to delete old model "${originalName}" during rename: ${err instanceof Error ? err.message : String(err)}`);
179
+ }
180
+ }
181
+ await saveCustomModel(model);
182
+ onComplete(model);
183
+ }
184
+ catch (err) {
185
+ logger.error(`Failed to save custom model: ${err instanceof Error ? err.message : 'Unknown error'}`);
186
+ setError(`Failed to save: ${err instanceof Error ? err.message : 'Unknown error'}`);
187
+ setIsSaving(false);
188
+ }
189
+ }, [selectedProvider, providerConfig, originalName, onComplete]);
129
190
  const handleBack = useCallback(() => {
130
191
  if (currentStep > 0) {
131
192
  setCurrentStep(currentStep - 1);
132
193
  // Restore previous value
133
- const prevStep = WIZARD_STEPS[currentStep - 1];
194
+ const prevStep = wizardSteps[currentStep - 1];
134
195
  if (prevStep) {
135
196
  setCurrentInput(values[prevStep.field] || '');
136
197
  }
137
198
  setError(null);
138
199
  }
200
+ else if (selectedProvider) {
201
+ // Go back to provider selection
202
+ setSelectedProvider(null);
203
+ setError(null);
204
+ }
139
205
  else {
140
206
  onClose();
141
207
  }
142
- }, [currentStep, onClose, values]);
208
+ }, [currentStep, onClose, selectedProvider, values, wizardSteps]);
143
209
  // Handle keyboard input
144
210
  useImperativeHandle(ref, () => ({
145
211
  handleInput: (input, key) => {
146
- if (!isVisible || isSaving)
212
+ if (!isVisible || isSaving || isValidating)
147
213
  return false;
214
+ // Delegate to LocalModelWizard when local provider is selected
215
+ if (selectedProvider === 'local' && localModelWizardRef.current) {
216
+ return localModelWizardRef.current.handleInput(input, key);
217
+ }
148
218
  // Escape to go back/close
149
219
  if (key.escape) {
150
220
  handleBack();
151
221
  return true;
152
222
  }
153
- // Enter to submit current step
223
+ // Provider selection mode
224
+ if (!selectedProvider) {
225
+ const providers = getAvailableProviders();
226
+ if (key.upArrow) {
227
+ setProviderIndex((prev) => prev > 0 ? prev - 1 : providers.length - 1);
228
+ return true;
229
+ }
230
+ if (key.downArrow) {
231
+ setProviderIndex((prev) => prev < providers.length - 1 ? prev + 1 : 0);
232
+ return true;
233
+ }
234
+ if (key.return) {
235
+ handleProviderSelect();
236
+ return true;
237
+ }
238
+ return true; // Consume all input during provider selection
239
+ }
240
+ // Wizard step mode
154
241
  if (key.return) {
155
242
  void handleNext();
156
243
  return true;
@@ -169,9 +256,31 @@ const CustomModelWizard = forwardRef(function CustomModelWizard({ isVisible, onC
169
256
  }
170
257
  return false;
171
258
  },
172
- }), [isVisible, isSaving, handleBack, handleNext]);
173
- if (!isVisible || !currentStepConfig)
259
+ }), [
260
+ isVisible,
261
+ isSaving,
262
+ isValidating,
263
+ handleBack,
264
+ handleNext,
265
+ handleProviderSelect,
266
+ selectedProvider,
267
+ ]);
268
+ if (!isVisible)
269
+ return null;
270
+ // Provider selection screen (using shared component)
271
+ if (!selectedProvider) {
272
+ return _jsx(ProviderSelector, { selectedIndex: providerIndex, isEditing: isEditing });
273
+ }
274
+ // Local provider uses specialized wizard with download support
275
+ if (selectedProvider === 'local') {
276
+ return (_jsx(LocalModelWizard, { ref: localModelWizardRef, isVisible: isVisible, onComplete: onComplete, onClose: () => {
277
+ // Go back to provider selection instead of closing completely
278
+ setSelectedProvider(null);
279
+ } }));
280
+ }
281
+ // Wizard steps screen for other providers
282
+ if (!currentStepConfig || !providerConfig)
174
283
  return null;
175
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1, marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "green", children: "Add Custom Model" }), _jsxs(Text, { dimColor: true, children: [' ', "(Step ", currentStep + 1, "/", WIZARD_STEPS.length, ")"] })] }), _jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: [currentStepConfig.label, ":"] }), _jsx(Text, { dimColor: true, children: currentStepConfig.placeholder })] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "> " }), _jsx(Text, { children: currentInput }), _jsx(Text, { color: "cyan", children: "_" })] }), error && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "red", children: error }) })), isSaving && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "yellow", children: "Saving..." }) })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Enter to continue \u2022 Esc to ", currentStep > 0 ? 'go back' : 'cancel'] }) })] }));
284
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1, marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "green", children: isEditing ? 'Edit Custom Model' : 'Add Custom Model' }), _jsxs(Text, { color: "gray", children: [' ', "(", providerConfig.displayName, ") Step ", currentStep + 1, "/", wizardSteps.length] })] }), providerConfig.setupInfo && currentStep === 0 && (_jsx(SetupInfoBanner, { title: providerConfig.setupInfo.title, description: providerConfig.setupInfo.description, docsUrl: providerConfig.setupInfo.docsUrl })), _jsx(WizardStepInput, { step: currentStepConfig, currentInput: currentInput, error: error, isValidating: isValidating, isSaving: isSaving, additionalContent: currentStepConfig.field === 'apiKey' ? (_jsx(ApiKeyStep, { provider: selectedProvider })) : undefined }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", children: ["Enter to continue \u2022 Esc to", ' ', currentStep > 0 ? 'go back' : 'back to provider'] }) })] }));
176
285
  });
177
286
  export default CustomModelWizard;
@@ -1 +1 @@
1
- {"version":3,"file":"LogLevelSelector.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/LogLevelSelector.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,EAAE,MAAM,aAAa,CAAC;AAG9C,UAAU,qBAAqB;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAkBD;;GAEG;AACH,QAAA,MAAM,gBAAgB,sGA8FrB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"LogLevelSelector.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/LogLevelSelector.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,EAAE,MAAM,aAAa,CAAC;AAG9C,UAAU,qBAAqB;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAkBD;;GAEG;AACH,QAAA,MAAM,gBAAgB,sGAyFrB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -49,11 +49,11 @@ const LogLevelSelector = forwardRef(function LogLevelSelector({ isVisible, onSel
49
49
  }
50
50
  }, [isVisible, agent]);
51
51
  // Format level item for display
52
- const formatItem = (option, isSelected) => (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [option.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: option.level }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', dimColor: !isSelected, children: [' ', "- ", option.description] }), option.isCurrent && (_jsxs(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: [' ', "\u2190 Current"] }))] }));
52
+ const formatItem = (option, isSelected) => (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [option.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: option.level }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [" - ", option.description] }), option.isCurrent && (_jsxs(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: [' ', "\u2190 Current"] }))] }));
53
53
  // Handle selection
54
54
  const handleSelect = (option) => {
55
55
  onSelect(option.level);
56
56
  };
57
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(BaseSelector, { ref: baseSelectorRef, items: levels, isVisible: isVisible, isLoading: false, selectedIndex: selectedIndex, onSelectIndex: setSelectedIndex, onSelect: handleSelect, onClose: onClose, formatItem: formatItem, title: "Select Log Level", borderColor: "yellow", emptyMessage: "No log levels available" }), logFilePath && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", dimColor: true, children: ["\uD83D\uDCC1 Log file: ", logFilePath] }) }))] }));
57
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(BaseSelector, { ref: baseSelectorRef, items: levels, isVisible: isVisible, isLoading: false, selectedIndex: selectedIndex, onSelectIndex: setSelectedIndex, onSelect: handleSelect, onClose: onClose, formatItem: formatItem, title: "Select Log Level", borderColor: "yellowBright", emptyMessage: "No log levels available" }), logFilePath && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", children: ["\uD83D\uDCC1 Log file: ", logFilePath] }) }))] }));
58
58
  });
59
59
  export default LogLevelSelector;
@@ -1 +1 @@
1
- {"version":3,"file":"McpAddChoice.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpAddChoice.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAuE,MAAM,OAAO,CAAC;AAE5F,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAG/D,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE9D,UAAU,iBAAiB;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7C,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAC/B,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAkCD;;GAEG;AACH,QAAA,MAAM,YAAY,8FA4DhB,CAAC;AAEH,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"McpAddChoice.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpAddChoice.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAuE,MAAM,OAAO,CAAC;AAE5F,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAG/D,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE9D,UAAU,iBAAiB;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7C,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAC/B,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAkCD;;GAEG;AACH,QAAA,MAAM,YAAY,8FAyDhB,CAAC;AAEH,eAAe,YAAY,CAAC"}
@@ -49,7 +49,7 @@ const McpAddChoice = forwardRef(function McpAddChoice({ isVisible, onSelect, onC
49
49
  }
50
50
  }, [isVisible]);
51
51
  // Format item for display
52
- const formatItem = (item, isSelected) => (_jsxs(Box, { children: [_jsxs(Text, { children: [item.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: item.label }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', dimColor: !isSelected, children: [' ', "- ", item.description] })] }));
52
+ const formatItem = (item, isSelected) => (_jsxs(Box, { children: [_jsxs(Text, { children: [item.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: item.label }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [" - ", item.description] })] }));
53
53
  // Handle selection
54
54
  const handleSelect = (item) => {
55
55
  onSelect(item.type);
@@ -63,7 +63,7 @@ const McpAddSelector = forwardRef(function McpAddSelector({ isVisible, onSelect,
63
63
  };
64
64
  }, [isVisible]);
65
65
  // Format option for display
66
- const formatItem = (option, isSelected) => (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [option.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: option.label }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', dimColor: !isSelected, children: [' ', "- ", option.description.slice(0, 40), option.description.length > 40 ? '...' : ''] })] }));
66
+ const formatItem = (option, isSelected) => (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [option.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: option.label }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [' ', "- ", option.description.slice(0, 40), option.description.length > 40 ? '...' : ''] })] }));
67
67
  // Handle selection
68
68
  const handleSelect = (option) => {
69
69
  onSelect({ type: 'preset', entry: option.entry });
@@ -1 +1 @@
1
- {"version":3,"file":"McpCustomTypeSelector.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpCustomTypeSelector.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,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,UAAU,0BAA0B;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;IAC9C,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,2BAA2B;IACxC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AA8BD;;GAEG;AACH,QAAA,MAAM,qBAAqB,gHAwD1B,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"McpCustomTypeSelector.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpCustomTypeSelector.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,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,UAAU,0BAA0B;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;IAC9C,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,2BAA2B;IACxC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AA8BD;;GAEG;AACH,QAAA,MAAM,qBAAqB,gHAqD1B,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
@@ -42,10 +42,10 @@ const McpCustomTypeSelector = forwardRef(function McpCustomTypeSelector({ isVisi
42
42
  setSelectedIndex(0);
43
43
  }
44
44
  }, [isVisible]);
45
- const formatItem = (option, isSelected) => (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [option.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: option.label }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', dimColor: !isSelected, children: [' ', "- ", option.description] })] }));
45
+ const formatItem = (option, isSelected) => (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [option.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: option.label }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [" - ", option.description] })] }));
46
46
  const handleSelect = (option) => {
47
47
  onSelect(option.type);
48
48
  };
49
- return (_jsx(BaseSelector, { ref: baseSelectorRef, items: SERVER_TYPE_OPTIONS, isVisible: isVisible, isLoading: false, selectedIndex: selectedIndex, onSelectIndex: setSelectedIndex, onSelect: handleSelect, onClose: onClose, formatItem: formatItem, title: "Select Server Type", borderColor: "yellow", emptyMessage: "No options available" }));
49
+ return (_jsx(BaseSelector, { ref: baseSelectorRef, items: SERVER_TYPE_OPTIONS, isVisible: isVisible, isLoading: false, selectedIndex: selectedIndex, onSelectIndex: setSelectedIndex, onSelect: handleSelect, onClose: onClose, formatItem: formatItem, title: "Select Server Type", borderColor: "yellowBright", emptyMessage: "No options available" }));
50
50
  });
51
51
  export default McpCustomTypeSelector;
@@ -210,6 +210,6 @@ const McpCustomWizard = forwardRef(function McpCustomWizard({ isVisible, serverT
210
210
  if (!isVisible || !currentStepConfig)
211
211
  return null;
212
212
  const serverTypeLabel = serverType.toUpperCase();
213
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "yellow", children: ["Add Custom ", serverTypeLabel, " Server"] }), _jsxs(Text, { dimColor: true, children: [' ', "(Step ", currentStep + 1, "/", steps.length, ")"] })] }), _jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: [currentStepConfig.label, ":"] }), _jsx(Text, { dimColor: true, children: currentStepConfig.placeholder })] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "> " }), _jsx(Text, { children: currentInput }), _jsx(Text, { color: "cyan", children: "_" })] }), error && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "red", children: error }) })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Enter to continue \u2022 Esc to ", currentStep > 0 ? 'go back' : 'cancel'] }) })] }));
213
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellowBright", paddingX: 1, marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "yellowBright", children: ["Add Custom ", serverTypeLabel, " Server"] }), _jsxs(Text, { color: "gray", children: [' ', "(Step ", currentStep + 1, "/", steps.length, ")"] })] }), _jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: [currentStepConfig.label, ":"] }), _jsx(Text, { color: "gray", children: currentStepConfig.placeholder })] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "> " }), _jsx(Text, { children: currentInput }), _jsx(Text, { color: "cyan", children: "_" })] }), error && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "red", children: error }) })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", children: ["Enter to continue \u2022 Esc to ", currentStep > 0 ? 'go back' : 'cancel'] }) })] }));
214
214
  });
215
215
  export default McpCustomWizard;
@@ -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,wGAoHtB,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,wGAmHtB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -64,7 +64,7 @@ const McpRemoveSelector = forwardRef(function McpRemoveSelector({ isVisible, onS
64
64
  ? 'green'
65
65
  : server.status === 'disconnected'
66
66
  ? 'gray'
67
- : 'red', dimColor: !isSelected, children: [' ', "- ", getStatusText(server.status)] }), server.error && (_jsxs(Text, { color: "gray", dimColor: true, children: [' ', "(", server.error.slice(0, 30), server.error.length > 30 ? '...' : '', ")"] }))] }));
67
+ : 'red', children: [' ', "- ", getStatusText(server.status)] }), server.error && (_jsxs(Text, { color: "gray", children: [' ', "(", server.error.slice(0, 30), server.error.length > 30 ? '...' : '', ")"] }))] }));
68
68
  // Handle selection
69
69
  const handleSelect = (server) => {
70
70
  onSelect(server.name);
@@ -1 +1 @@
1
- {"version":3,"file":"McpSelector.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpSelector.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAuE,MAAM,OAAO,CAAC;AAE5F,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAG/D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;AAExE,UAAU,gBAAgB;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IACtC,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAC9B,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AA0BD;;GAEG;AACH,QAAA,MAAM,WAAW,4FA8Df,CAAC;AAEH,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"McpSelector.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/McpSelector.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAuE,MAAM,OAAO,CAAC;AAE5F,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAG/D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;AAExE,UAAU,gBAAgB;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IACtC,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAC9B,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AA0BD;;GAEG;AACH,QAAA,MAAM,WAAW,4FA2Df,CAAC;AAEH,eAAe,WAAW,CAAC"}
@@ -42,7 +42,7 @@ const McpSelector = forwardRef(function McpSelector({ isVisible, onSelect, onClo
42
42
  }
43
43
  }, [isVisible]);
44
44
  // Format option for display
45
- const formatItem = (option, isSelected) => (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [option.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: option.label }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', dimColor: !isSelected, children: [' ', "- ", option.description] })] }));
45
+ const formatItem = (option, isSelected) => (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [option.icon, " "] }), _jsx(Text, { color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: option.label }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [" - ", option.description] })] }));
46
46
  // Handle selection
47
47
  const handleSelect = (option) => {
48
48
  onSelect(option.action);
@@ -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,sGA8GrB,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,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"}
@@ -37,7 +37,7 @@ const McpServerActions = forwardRef(function McpServerActions({ isVisible, serve
37
37
  type: 'disable',
38
38
  label: 'Disable server',
39
39
  icon: '⏸️',
40
- color: 'yellow',
40
+ color: 'orange',
41
41
  });
42
42
  }
43
43
  else {
@@ -69,7 +69,7 @@ const McpServerActions = forwardRef(function McpServerActions({ isVisible, serve
69
69
  }, [server]);
70
70
  // Format item for display
71
71
  const formatItem = (item, isSelected) => {
72
- return (_jsxs(Box, { children: [_jsxs(Text, { children: [item.icon, " "] }), _jsx(Text, { color: isSelected ? item.color : 'gray', bold: isSelected, dimColor: !isSelected, children: item.label })] }));
72
+ return (_jsxs(Box, { children: [_jsxs(Text, { children: [item.icon, " "] }), _jsx(Text, { color: isSelected ? item.color : 'gray', bold: isSelected, children: item.label })] }));
73
73
  };
74
74
  // Handle selection
75
75
  const handleSelect = (item) => {
@@ -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,gGA6HjB,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;AAoCD;;GAEG;AACH,QAAA,MAAM,aAAa,gGA4HjB,CAAC;AAEH,eAAe,aAAa,CAAC"}
@@ -93,7 +93,7 @@ const McpServerList = forwardRef(function McpServerList({ isVisible, onAction, o
93
93
  ? 'green'
94
94
  : server.status === 'disconnected'
95
95
  ? 'gray'
96
- : 'red', dimColor: !isSelected, children: ["[", statusText, "]"] })] }));
96
+ : 'red', children: ["[", statusText, "]"] })] }));
97
97
  };
98
98
  // Handle selection
99
99
  const handleSelect = (item) => {
@@ -2,17 +2,17 @@
2
2
  * ModelSelector Component (Refactored)
3
3
  * Features:
4
4
  * - Search filtering
5
- * - Custom models support (add/delete)
6
- * - Keyboard shortcuts: Shift+D to delete custom model
5
+ * - Custom models support (add/edit/delete via arrow navigation)
7
6
  */
8
- import React from 'react';
9
7
  import type { Key } from '../../hooks/useInputOrchestrator.js';
10
8
  import type { DextoAgent, LLMProvider } from '@dexto/core';
9
+ import { type CustomModel } from '@dexto/agent-management';
11
10
  interface ModelSelectorProps {
12
11
  isVisible: boolean;
13
- onSelectModel: (provider: LLMProvider, model: string, baseURL?: string) => void;
12
+ onSelectModel: (provider: LLMProvider, model: string, displayName?: string, baseURL?: string) => void;
14
13
  onClose: () => void;
15
14
  onAddCustomModel: () => void;
15
+ onEditCustomModel: (model: CustomModel) => void;
16
16
  agent: DextoAgent;
17
17
  }
18
18
  export interface ModelSelectorHandle {
@@ -21,6 +21,6 @@ export interface ModelSelectorHandle {
21
21
  /**
22
22
  * Model selector with search and custom model support
23
23
  */
24
- declare const ModelSelector: React.ForwardRefExoticComponent<ModelSelectorProps & React.RefAttributes<ModelSelectorHandle>>;
24
+ declare const ModelSelector: import("react").ForwardRefExoticComponent<ModelSelectorProps & import("react").RefAttributes<ModelSelectorHandle>>;
25
25
  export default ModelSelector;
26
26
  //# sourceMappingURL=ModelSelectorRefactored.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ModelSelectorRefactored.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/ModelSelectorRefactored.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG3D,UAAU,kBAAkB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAChF,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AA0BD;;GAEG;AACH,QAAA,MAAM,aAAa,gGAyZjB,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;AAE3D,OAAO,EAIH,KAAK,WAAW,EACnB,MAAM,yBAAyB,CAAC;AAEjC,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,KACf,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;AA0BD;;GAEG;AACH,QAAA,MAAM,aAAa,oHAmmBjB,CAAC;AAEH,eAAe,aAAa,CAAC"}