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
@@ -3,11 +3,13 @@ import chalk from 'chalk';
3
3
  import { z } from 'zod';
4
4
  import { getDefaultModelForProvider, LLM_PROVIDERS, LLM_REGISTRY, isValidProviderModel, getSupportedModels, acceptsAnyModel, supportsCustomModels, requiresApiKey, isReasoningCapableModel, } from '@dexto/core';
5
5
  import { resolveApiKeyForProvider } from '@dexto/core';
6
- import { createInitialPreferences, saveGlobalPreferences, loadGlobalPreferences, getGlobalPreferencesPath, updateGlobalPreferences, setActiveModel, } from '@dexto/agent-management';
6
+ import { createInitialPreferences, saveGlobalPreferences, loadGlobalPreferences, getGlobalPreferencesPath, updateGlobalPreferences, setActiveModel, isDextoAuthEnabled, } from '@dexto/agent-management';
7
7
  import { interactiveApiKeySetup, hasApiKeyConfigured } from '../utils/api-key-setup.js';
8
8
  import { selectProvider, getProviderDisplayName, getProviderEnvVar, providerRequiresBaseURL, getDefaultModel, } from '../utils/provider-setup.js';
9
9
  import { setupLocalModels, setupOllamaModels, hasSelectedModel, getModelFromResult, } from '../utils/local-model-setup.js';
10
10
  import { requiresSetup } from '../utils/setup-utils.js';
11
+ import { canUseDextoProvider } from '../utils/dexto-setup.js';
12
+ import { handleBrowserLogin } from './auth/login.js';
11
13
  import * as p from '@clack/prompts';
12
14
  import { logger } from '@dexto/core';
13
15
  import { capture } from '../../analytics/index.js';
@@ -155,19 +157,90 @@ export async function handleSetupCommand(options) {
155
157
  await handleNonInteractiveSetup(validated);
156
158
  }
157
159
  /**
158
- * Quick start flow - uses Google Gemini with minimal prompts
160
+ * Quick start flow - pick a free provider with minimal prompts
159
161
  */
160
162
  async function handleQuickStart() {
161
- console.log(chalk.cyan('\n🚀 Quick Start with Google Gemini\n'));
163
+ console.log(chalk.cyan('\n🚀 Quick Start\n'));
162
164
  p.intro(chalk.cyan('Quick Setup'));
163
- const provider = 'google';
164
- const model = getDefaultModelForProvider(provider) || 'gemini-2.5-pro';
165
+ // Let user pick from popular free providers
166
+ const quickProvider = await p.select({
167
+ message: 'Choose a provider',
168
+ options: [
169
+ {
170
+ value: 'google',
171
+ label: `${chalk.green('●')} Google Gemini`,
172
+ hint: 'Free, 1M+ context (recommended)',
173
+ },
174
+ {
175
+ value: 'groq',
176
+ label: `${chalk.green('●')} Groq`,
177
+ hint: 'Free, ultra-fast',
178
+ },
179
+ {
180
+ value: 'local',
181
+ label: `${chalk.cyan('●')} Local Models`,
182
+ hint: 'Free, private, runs on your machine',
183
+ },
184
+ ],
185
+ });
186
+ if (p.isCancel(quickProvider)) {
187
+ p.cancel('Setup cancelled');
188
+ process.exit(0);
189
+ }
190
+ // Handle local models with dedicated setup flow
191
+ if (quickProvider === 'local') {
192
+ const localResult = await setupLocalModels();
193
+ if (!hasSelectedModel(localResult)) {
194
+ p.cancel('Setup cancelled');
195
+ process.exit(0);
196
+ }
197
+ const model = getModelFromResult(localResult);
198
+ // CLI mode confirmation for local
199
+ const useCli = await p.confirm({
200
+ message: 'Start in Terminal mode? (You can change this later)',
201
+ initialValue: true,
202
+ });
203
+ if (p.isCancel(useCli)) {
204
+ p.cancel('Setup cancelled');
205
+ process.exit(0);
206
+ }
207
+ const defaultMode = useCli ? 'cli' : await selectDefaultMode();
208
+ if (defaultMode === null) {
209
+ p.cancel('Setup cancelled');
210
+ process.exit(0);
211
+ }
212
+ // Sync the active model for local provider
213
+ await setActiveModel(model);
214
+ const preferences = createInitialPreferences({
215
+ provider: 'local',
216
+ model,
217
+ defaultMode,
218
+ setupCompleted: true,
219
+ apiKeyPending: false,
220
+ });
221
+ await saveGlobalPreferences(preferences);
222
+ capture('dexto_setup', {
223
+ provider: 'local',
224
+ model,
225
+ setupMode: 'interactive',
226
+ setupVariant: 'quick-start',
227
+ defaultMode,
228
+ apiKeySkipped: false,
229
+ });
230
+ await showSetupComplete('local', model, defaultMode, false);
231
+ return;
232
+ }
233
+ // Cloud provider flow (google or groq)
234
+ const provider = quickProvider;
235
+ const model = getDefaultModelForProvider(provider) ||
236
+ (provider === 'google' ? 'gemini-2.5-pro' : 'llama-3.3-70b-versatile');
165
237
  const apiKeyVar = getProviderEnvVar(provider);
166
238
  let apiKeySkipped = false;
167
239
  // Check if API key exists
168
240
  const hasKey = hasApiKeyConfigured(provider);
169
241
  if (!hasKey) {
170
- p.note(`Google Gemini is ${chalk.green('free')} to use!\n\n` +
242
+ const providerName = getProviderDisplayName(provider);
243
+ p.note(`${providerName} is ${chalk.green('free')} to use!\n\n` +
171
244
  `We'll help you get an API key in just a few seconds.`, 'Free AI Access');
172
245
  const result = await interactiveApiKeySetup(provider, {
173
246
  exitOnCancel: false, // Don't exit - allow skipping
@@ -184,8 +257,16 @@ async function handleQuickStart() {
184
257
  else {
185
258
  p.log.success(`API key for ${getProviderDisplayName(provider)} already configured`);
186
259
  }
187
- // Ask about default mode
188
- const defaultMode = await selectDefaultMode();
260
+ // CLI mode confirmation
261
+ const useCli = await p.confirm({
262
+ message: 'Start in Terminal mode? (You can change this later)',
263
+ initialValue: true,
264
+ });
265
+ if (p.isCancel(useCli)) {
266
+ p.cancel('Setup cancelled');
267
+ process.exit(0);
268
+ }
269
+ const defaultMode = useCli ? 'cli' : await selectDefaultMode();
189
270
  // Handle cancellation
190
271
  if (defaultMode === null) {
191
272
  p.cancel('Setup cancelled');
@@ -213,7 +294,153 @@ async function handleQuickStart() {
213
294
  defaultMode,
214
295
  apiKeySkipped,
215
296
  });
216
- showSetupComplete(provider, model, defaultMode, apiKeySkipped);
297
+ await showSetupComplete(provider, model, defaultMode, apiKeySkipped);
298
+ }
299
+ /**
300
+ * Dexto setup flow - login if needed, select model, save preferences
301
+ *
302
+ * Config storage:
303
+ * - provider: 'dexto' (the gateway provider)
304
+ * - model: OpenRouter-style ID (e.g., 'anthropic/claude-haiku-4.5')
305
+ *
306
+ * Runtime handles routing requests through the Dexto gateway to the underlying provider.
307
+ */
308
+ async function handleDextoProviderSetup() {
309
+ console.log(chalk.magenta('\n★ Dexto Setup\n'));
310
+ // Check if user already has DEXTO_API_KEY
311
+ const hasKey = await canUseDextoProvider();
312
+ if (!hasKey) {
313
+ p.note(`Dexto gives you instant access to ${chalk.cyan('all AI models')} with a single account.\n\n` +
314
+ `We'll open your browser to sign in or create an account.`, 'Login Required');
315
+ const shouldLogin = await p.confirm({
316
+ message: 'Continue with browser login?',
317
+ initialValue: true,
318
+ });
319
+ if (p.isCancel(shouldLogin) || !shouldLogin) {
320
+ p.cancel('Setup cancelled');
321
+ process.exit(0);
322
+ }
323
+ try {
324
+ await handleBrowserLogin();
325
+ // Verify key was actually provisioned (provisionKeys silently catches errors)
326
+ if (!(await canUseDextoProvider())) {
327
+ p.log.error('API key provisioning failed. Please try again or use `dexto setup` with a different provider.');
328
+ process.exit(1);
329
+ }
330
+ p.log.success('Login successful! Continuing with setup...');
331
+ }
332
+ catch (error) {
333
+ const errorMessage = error instanceof Error ? error.message : String(error);
334
+ p.log.error(`Login failed: ${errorMessage}`);
335
+ p.cancel('Setup cancelled - login required for Dexto');
336
+ process.exit(1);
337
+ }
338
+ }
339
+ else {
340
+ p.log.success('Already logged in to Dexto');
341
+ }
342
+ // Model selection - show popular models in OpenRouter format
343
+ // NOTE: This list is intentionally hardcoded (not from registry) to include
344
+ // curated hints for onboarding UX. Keep model IDs in sync with:
345
+ // packages/core/src/llm/registry.ts (LLM_REGISTRY.dexto.models)
346
+ const model = await p.select({
347
+ message: 'Select a model to start with',
348
+ options: [
349
+ // Claude models (Anthropic via Dexto gateway)
350
+ {
351
+ value: 'anthropic/claude-haiku-4.5',
352
+ label: 'Claude 4.5 Haiku',
353
+ hint: 'Fast & affordable (recommended)',
354
+ },
355
+ {
356
+ value: 'anthropic/claude-sonnet-4.5',
357
+ label: 'Claude 4.5 Sonnet',
358
+ hint: 'Balanced performance and cost',
359
+ },
360
+ {
361
+ value: 'anthropic/claude-opus-4.5',
362
+ label: 'Claude 4.5 Opus',
363
+ hint: 'Most capable Claude model',
364
+ },
365
+ // OpenAI models (via Dexto gateway)
366
+ {
367
+ value: 'openai/gpt-5.2',
368
+ label: 'GPT-5.2',
369
+ hint: 'OpenAI flagship model',
370
+ },
371
+ {
372
+ value: 'openai/gpt-5.2-codex',
373
+ label: 'GPT-5.2 Codex',
374
+ hint: 'Optimized for coding',
375
+ },
376
+ // Google models (via Dexto gateway)
377
+ {
378
+ value: 'google/gemini-3-pro-preview',
379
+ label: 'Gemini 3 Pro',
380
+ hint: 'Google flagship model',
381
+ },
382
+ {
383
+ value: 'google/gemini-3-flash-preview',
384
+ label: 'Gemini 3 Flash',
385
+ hint: 'Fast and efficient',
386
+ },
387
+ // Free models (via Dexto gateway)
388
+ {
389
+ value: 'qwen/qwen3-coder:free',
390
+ label: 'Qwen3 Coder (Free)',
391
+ hint: 'Free coding model, 262k context',
392
+ },
393
+ {
394
+ value: 'deepseek/deepseek-r1-0528:free',
395
+ label: 'DeepSeek R1 (Free)',
396
+ hint: 'Free reasoning model, 163k context',
397
+ },
398
+ // Other models (via Dexto gateway)
399
+ {
400
+ value: 'z-ai/glm-4.7',
401
+ label: 'GLM 4.7',
402
+ hint: 'Zhipu AI flagship model',
403
+ },
404
+ {
405
+ value: 'minimax/minimax-m2.1',
406
+ label: 'Minimax M2.1',
407
+ hint: 'Fast model with 196k context',
408
+ },
409
+ ],
410
+ });
411
+ if (p.isCancel(model)) {
412
+ p.cancel('Setup cancelled');
413
+ process.exit(0);
414
+ }
415
+ // Dexto setup always uses 'dexto' provider with OpenRouter model IDs
416
+ const provider = 'dexto';
417
+ // Cast model to string (prompts library typing)
418
+ const selectedModel = model;
419
+ p.log.info(`${chalk.dim('Tip:')} You can switch models anytime with ${chalk.cyan('/model')}`);
420
+ // Ask about default mode
421
+ const defaultMode = await selectDefaultMode();
422
+ if (defaultMode === null) {
423
+ p.cancel('Setup cancelled');
424
+ process.exit(0);
425
+ }
426
+ // Save preferences with explicit dexto provider and OpenRouter model ID
427
+ const preferences = createInitialPreferences({
428
+ provider,
429
+ model: selectedModel,
430
+ defaultMode,
431
+ setupCompleted: true,
432
+ apiKeyPending: false,
433
+ apiKeyVar: 'DEXTO_API_KEY',
434
+ });
435
+ await saveGlobalPreferences(preferences);
436
+ capture('dexto_setup', {
437
+ provider,
438
+ model: selectedModel,
439
+ setupMode: 'interactive',
440
+ setupVariant: 'dexto',
441
+ defaultMode,
442
+ });
443
+ await showSetupComplete(provider, selectedModel, defaultMode, false);
217
444
  }
218
445
  /**
219
446
  * Full interactive setup flow with wizard navigation.
@@ -257,25 +484,37 @@ async function handleInteractiveSetup(_options) {
257
484
  * Wizard Step: Setup Type (Quick Start vs Custom)
258
485
  */
259
486
  async function wizardStepSetupType(state) {
487
+ // Build options list - only show Dexto Credits when feature is enabled
488
+ const options = [];
489
+ if (isDextoAuthEnabled()) {
490
+ options.push({
491
+ value: 'dexto',
492
+ label: `${chalk.magenta('★')} Dexto Credits`,
493
+ hint: 'All models, one account - login to get started (recommended)',
494
+ });
495
+ }
496
+ options.push({
497
+ value: 'quick',
498
+ label: `${chalk.green('●')} Quick Start`,
499
+ hint: 'Google Gemini (free) - no account needed',
500
+ }, {
501
+ value: 'custom',
502
+ label: `${chalk.blue('●')} Custom Setup`,
503
+ hint: 'Choose your provider (OpenAI, Anthropic, Ollama, etc.)',
504
+ });
260
505
  const setupType = await p.select({
261
506
  message: 'How would you like to set up Dexto?',
262
- options: [
263
- {
264
- value: 'quick',
265
- label: `${chalk.green('●')} Quick Start`,
266
- hint: 'Google Gemini (free) - recommended for new users',
267
- },
268
- {
269
- value: 'custom',
270
- label: `${chalk.blue('●')} Custom Setup`,
271
- hint: 'Choose your provider (OpenAI, Anthropic, Ollama, etc.)',
272
- },
273
- ],
507
+ options,
274
508
  });
275
509
  if (p.isCancel(setupType)) {
276
510
  p.cancel('Setup cancelled');
277
511
  process.exit(0);
278
512
  }
513
+ if (setupType === 'dexto') {
514
+ // Handle Dexto Credits flow - login if needed, then proceed to model selection
515
+ await handleDextoProviderSetup();
516
+ return { ...state, step: 'complete', quickStartHandled: true };
517
+ }
279
518
  if (setupType === 'quick') {
280
519
  // Quick start bypasses the wizard - handle it directly
281
520
  await handleQuickStart();
@@ -494,18 +733,18 @@ async function selectDefaultModeWithBack() {
494
733
  options: [
495
734
  {
496
735
  value: 'cli',
497
- label: `${chalk.green('●')} Terminal CLI`,
498
- hint: 'Interactive command-line interface (recommended)',
736
+ label: `${chalk.green('●')} Terminal`,
737
+ hint: 'Chat in your terminal (most popular)',
499
738
  },
500
739
  {
501
740
  value: 'web',
502
- label: `${chalk.blue('●')} Web UI`,
503
- hint: 'Opens in browser at localhost:3000',
741
+ label: `${chalk.blue('●')} Browser`,
742
+ hint: 'Web UI at localhost:3000',
504
743
  },
505
744
  {
506
745
  value: 'server',
507
- label: `${chalk.rgb(255, 165, 0)('●')} API Server`,
508
- hint: 'REST API for programmatic access',
746
+ label: `${chalk.cyan('●')} API Server`,
747
+ hint: 'REST API for integrations',
509
748
  },
510
749
  { value: '_back', label: chalk.gray('← Back'), hint: 'Go to previous step' },
511
750
  ],
@@ -558,7 +797,7 @@ async function saveWizardPreferences(state) {
558
797
  hasBaseURL: Boolean(state.baseURL),
559
798
  apiKeySkipped,
560
799
  });
561
- showSetupComplete(provider, model, defaultMode, apiKeySkipped);
800
+ await showSetupComplete(provider, model, defaultMode, apiKeySkipped);
562
801
  }
563
802
  /**
564
803
  * Non-interactive setup with CLI options
@@ -661,7 +900,7 @@ async function showSettingsMenu() {
661
900
  });
662
901
  // Exit conditions
663
902
  if (p.isCancel(action) || action === 'exit') {
664
- p.outro(chalk.gray('Settings closed'));
903
+ p.outro(`Run ${chalk.cyan('dexto')} to start Dexto`);
665
904
  return;
666
905
  }
667
906
  // Execute action and loop back (except for reset which exits)
@@ -695,7 +934,40 @@ async function showSettingsMenu() {
695
934
  * Change model setting (includes provider selection)
696
935
  */
697
936
  async function changeModel(currentProvider) {
698
- const provider = currentProvider || (await selectProvider());
937
+ let provider = currentProvider ?? null;
938
+ // If no provider specified, show selection
939
+ // When Dexto auth is enabled, show Dexto/Other choice first (matching first-time setup flow)
940
+ if (!provider && isDextoAuthEnabled()) {
941
+ const providerChoice = await p.select({
942
+ message: 'Choose your model source',
943
+ options: [
944
+ {
945
+ value: 'dexto',
946
+ label: `${chalk.magenta('★')} Dexto Credits`,
947
+ hint: 'All models, one account',
948
+ },
949
+ {
950
+ value: 'other',
951
+ label: `${chalk.blue('●')} Other providers`,
952
+ hint: 'OpenAI, Anthropic, Gemini, Ollama, etc.',
953
+ },
954
+ ],
955
+ });
956
+ if (p.isCancel(providerChoice)) {
957
+ p.log.warn('Model change cancelled');
958
+ return;
959
+ }
960
+ if (providerChoice === 'dexto') {
961
+ // Use the same Dexto setup flow as first-time setup
962
+ await handleDextoProviderSetup();
963
+ return;
964
+ }
965
+ // 'other' - fall through to normal provider selection
966
+ }
967
+ // Get provider if not already set
968
+ if (!provider) {
969
+ provider = await selectProvider();
970
+ }
699
971
  // Handle cancellation or back from selectProvider
700
972
  if (provider === null || provider === '_back') {
701
973
  p.log.warn('Model change cancelled');
@@ -758,6 +1030,22 @@ async function changeModel(currentProvider) {
758
1030
  }
759
1031
  const apiKeyVar = getProviderEnvVar(provider);
760
1032
  const needsApiKey = requiresApiKey(provider);
1033
+ const hasKey = hasApiKeyConfigured(provider);
1034
+ // Check if API key is needed and missing - prompt for it
1035
+ if (needsApiKey && !hasKey) {
1036
+ const result = await interactiveApiKeySetup(provider, {
1037
+ exitOnCancel: false,
1038
+ model,
1039
+ });
1040
+ if (result.cancelled) {
1041
+ p.log.warn('Model change cancelled');
1042
+ return;
1043
+ }
1044
+ // If user skipped API key setup, still allow model change but warn
1045
+ if (result.skipped || !result.success) {
1046
+ p.log.warn(`API key setup was skipped. You'll need to configure ${apiKeyVar} before using this model.`);
1047
+ }
1048
+ }
761
1049
  const llmUpdate = {
762
1050
  provider,
763
1051
  model,
@@ -892,18 +1180,18 @@ async function selectDefaultMode() {
892
1180
  options: [
893
1181
  {
894
1182
  value: 'cli',
895
- label: `${chalk.green('●')} Terminal CLI`,
896
- hint: 'Interactive command-line interface (recommended)',
1183
+ label: `${chalk.green('●')} Terminal`,
1184
+ hint: 'Chat in your terminal (most popular)',
897
1185
  },
898
1186
  {
899
1187
  value: 'web',
900
- label: `${chalk.blue('●')} Web UI`,
901
- hint: 'Opens in browser at localhost:3000',
1188
+ label: `${chalk.blue('●')} Browser`,
1189
+ hint: 'Web UI at localhost:3000',
902
1190
  },
903
1191
  {
904
1192
  value: 'server',
905
- label: `${chalk.rgb(255, 165, 0)('●')} API Server`,
906
- hint: 'REST API for programmatic access',
1193
+ label: `${chalk.cyan('●')} API Server`,
1194
+ hint: 'REST API for integrations',
907
1195
  },
908
1196
  ],
909
1197
  });
@@ -1024,7 +1312,7 @@ async function promptForBaseURL(provider) {
1024
1312
  /**
1025
1313
  * Show setup complete message
1026
1314
  */
1027
- function showSetupComplete(provider, model, defaultMode, apiKeySkipped = false) {
1315
+ async function showSetupComplete(provider, model, defaultMode, apiKeySkipped = false) {
1028
1316
  const modeCommand = defaultMode === 'web' ? 'dexto' : `dexto --mode ${defaultMode}`;
1029
1317
  const isLocalProvider = provider === 'local' || provider === 'ollama';
1030
1318
  if (apiKeySkipped) {
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Options for the sync-agents command
3
+ */
4
+ export interface SyncAgentsCommandOptions {
5
+ /** Just list status without updating */
6
+ list?: boolean;
7
+ /** Update all without prompting */
8
+ force?: boolean;
9
+ /** Minimal output - used when called from startup prompt */
10
+ quiet?: boolean;
11
+ }
12
+ /**
13
+ * Mark sync as dismissed for current version
14
+ */
15
+ export declare function markSyncDismissed(currentVersion: string): Promise<void>;
16
+ /**
17
+ * Clear sync dismissed state (called after successful sync)
18
+ */
19
+ export declare function clearSyncDismissed(): Promise<void>;
20
+ /**
21
+ * Quick check if any installed agents have updates available
22
+ *
23
+ * Used at CLI startup to prompt for sync without full command output.
24
+ * Returns true if at least one installed agent differs from bundled
25
+ * AND the user hasn't dismissed the prompt for this version.
26
+ *
27
+ * @param currentVersion Current CLI version to check dismissal state
28
+ * @returns true if should prompt for sync
29
+ */
30
+ export declare function shouldPromptForSync(currentVersion: string): Promise<boolean>;
31
+ /**
32
+ * Main handler for the sync-agents command
33
+ *
34
+ * @param options Command options
35
+ *
36
+ * @example
37
+ * ```bash
38
+ * dexto sync-agents # Interactive - prompt for each
39
+ * dexto sync-agents --list # Show what would be updated
40
+ * dexto sync-agents --force # Update all without prompting
41
+ * ```
42
+ */
43
+ export declare function handleSyncAgentsCommand(options: SyncAgentsCommandOptions): Promise<void>;
44
+ //# sourceMappingURL=sync-agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-agents.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sync-agents.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACrC,wCAAwC;IACxC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,mCAAmC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAgND;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS7E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAWxD;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA8BlF;AAoDD;;;;;;;;;;;GAWG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiO9F"}