dexto 1.6.12 → 1.6.13

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 (68) hide show
  1. package/README.md +10 -2
  2. package/dist/analytics/events.d.ts +1 -1
  3. package/dist/analytics/events.d.ts.map +1 -1
  4. package/dist/cli/commands/agents/install.d.ts.map +1 -0
  5. package/dist/cli/commands/{install.js → agents/install.js} +4 -4
  6. package/dist/cli/commands/{list-agents.d.ts → agents/list.d.ts} +1 -1
  7. package/dist/cli/commands/agents/list.d.ts.map +1 -0
  8. package/dist/cli/commands/{list-agents.js → agents/list.js} +2 -2
  9. package/dist/cli/commands/agents/register.js +5 -5
  10. package/dist/cli/commands/{sync-agents.d.ts → agents/sync.d.ts} +10 -2
  11. package/dist/cli/commands/agents/sync.d.ts.map +1 -0
  12. package/dist/cli/commands/{sync-agents.js → agents/sync.js} +54 -5
  13. package/dist/cli/commands/agents/uninstall.d.ts +18 -0
  14. package/dist/cli/commands/agents/uninstall.d.ts.map +1 -0
  15. package/dist/cli/commands/agents/uninstall.js +141 -0
  16. package/dist/cli/commands/deploy/client.d.ts +44 -0
  17. package/dist/cli/commands/deploy/client.d.ts.map +1 -0
  18. package/dist/cli/commands/deploy/client.js +232 -0
  19. package/dist/cli/commands/deploy/config.d.ts +81 -0
  20. package/dist/cli/commands/deploy/config.d.ts.map +1 -0
  21. package/dist/cli/commands/deploy/config.js +144 -0
  22. package/dist/cli/commands/deploy/entry-agent.d.ts +3 -0
  23. package/dist/cli/commands/deploy/entry-agent.d.ts.map +1 -0
  24. package/dist/cli/commands/deploy/entry-agent.js +22 -0
  25. package/dist/cli/commands/deploy/index.d.ts +9 -0
  26. package/dist/cli/commands/deploy/index.d.ts.map +1 -0
  27. package/dist/cli/commands/deploy/index.js +204 -0
  28. package/dist/cli/commands/deploy/links.d.ts +3 -0
  29. package/dist/cli/commands/deploy/links.d.ts.map +1 -0
  30. package/dist/cli/commands/deploy/links.js +53 -0
  31. package/dist/cli/commands/deploy/register.d.ts +6 -0
  32. package/dist/cli/commands/deploy/register.d.ts.map +1 -0
  33. package/dist/cli/commands/deploy/register.js +75 -0
  34. package/dist/cli/commands/deploy/snapshot.d.ts +12 -0
  35. package/dist/cli/commands/deploy/snapshot.d.ts.map +1 -0
  36. package/dist/cli/commands/deploy/snapshot.js +76 -0
  37. package/dist/cli/commands/deploy/state.d.ts +21 -0
  38. package/dist/cli/commands/deploy/state.d.ts.map +1 -0
  39. package/dist/cli/commands/deploy/state.js +122 -0
  40. package/dist/cli/commands/index.d.ts +6 -4
  41. package/dist/cli/commands/index.d.ts.map +1 -1
  42. package/dist/cli/commands/index.js +6 -4
  43. package/dist/cli/commands/setup.d.ts.map +1 -1
  44. package/dist/cli/commands/setup.js +304 -31
  45. package/dist/cli/commands/uninstall.d.ts +9 -12
  46. package/dist/cli/commands/uninstall.d.ts.map +1 -1
  47. package/dist/cli/commands/uninstall.js +99 -113
  48. package/dist/cli/commands/upgrade.d.ts +15 -0
  49. package/dist/cli/commands/upgrade.d.ts.map +1 -0
  50. package/dist/cli/commands/upgrade.js +106 -0
  51. package/dist/cli/modes/cli.d.ts.map +1 -1
  52. package/dist/cli/modes/cli.js +0 -12
  53. package/dist/cli/utils/config-validation.d.ts.map +1 -1
  54. package/dist/cli/utils/config-validation.js +34 -20
  55. package/dist/cli/utils/self-management.d.ts +93 -0
  56. package/dist/cli/utils/self-management.d.ts.map +1 -0
  57. package/dist/cli/utils/self-management.js +423 -0
  58. package/dist/cli/utils/version-check.d.ts +1 -1
  59. package/dist/cli/utils/version-check.d.ts.map +1 -1
  60. package/dist/cli/utils/version-check.js +53 -19
  61. package/dist/index-main.js +59 -2
  62. package/dist/webui/assets/{index-CNiOYnOb.js → index-UDAdxmci.js} +187 -187
  63. package/dist/webui/index.html +1 -1
  64. package/package.json +13 -11
  65. package/dist/cli/commands/install.d.ts.map +0 -1
  66. package/dist/cli/commands/list-agents.d.ts.map +0 -1
  67. package/dist/cli/commands/sync-agents.d.ts.map +0 -1
  68. /package/dist/cli/commands/{install.d.ts → agents/install.d.ts} +0 -0
@@ -2,7 +2,7 @@
2
2
  import chalk from 'chalk';
3
3
  import { z } from 'zod';
4
4
  import open from 'open';
5
- import { acceptsAnyModel, getDefaultModelForProvider, getCuratedModelsForProvider, getReasoningProfile, getSupportedModels, LLM_PROVIDERS, LLM_REGISTRY, logger, isValidProviderModel, supportsCustomModels, requiresApiKey, resolveApiKeyForProvider, } from '@dexto/core';
5
+ import { acceptsAnyModel, CodexAppServerClient, createCodexBaseURL, getDefaultModelForProvider, getCodexAuthModeLabel, getCodexProviderDisplayName, getCuratedModelsForProvider, getReasoningProfile, getSupportedModels, isCodexBaseURL, LLM_PROVIDERS, LLM_REGISTRY, logger, parseCodexBaseURL, isValidProviderModel, supportsCustomModels, requiresApiKey, resolveApiKeyForProvider, } from '@dexto/core';
6
6
  import { createInitialPreferences, saveGlobalPreferences, loadGlobalPreferences, getGlobalPreferencesPath, updateGlobalPreferences, setActiveModel, isDextoAuthEnabled, loadCustomModels, saveCustomModel, deleteCustomModel, globalPreferencesExist, } 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';
@@ -408,6 +408,218 @@ async function handleQuickStart(options = { onCancel: 'exit' }) {
408
408
  return 'completed';
409
409
  }
410
410
  }
411
+ function getConfiguredProviderDisplayName(provider, baseURL) {
412
+ if (provider === 'openai-compatible') {
413
+ const codex = parseCodexBaseURL(baseURL);
414
+ if (codex) {
415
+ return getCodexProviderDisplayName(codex.authMode);
416
+ }
417
+ }
418
+ return getProviderDisplayName(provider);
419
+ }
420
+ function isCodexConfigured(provider, baseURL) {
421
+ return provider === 'openai-compatible' && isCodexBaseURL(baseURL);
422
+ }
423
+ async function ensureCodexChatGPTLogin(client) {
424
+ const spinner = p.spinner();
425
+ spinner.start('Starting ChatGPT login with Codex...');
426
+ const login = await client.startLogin({ type: 'chatgpt' });
427
+ if (login.type !== 'chatgpt') {
428
+ spinner.stop('ChatGPT login failed');
429
+ throw new Error('Codex did not return a ChatGPT login URL');
430
+ }
431
+ spinner.stop('ChatGPT login ready');
432
+ try {
433
+ await open(login.authUrl);
434
+ p.log.success('Opened your browser for ChatGPT login');
435
+ }
436
+ catch (error) {
437
+ const errorMessage = error instanceof Error ? error.message : String(error);
438
+ p.log.warn(`Could not open browser automatically: ${errorMessage}`);
439
+ }
440
+ p.note(`Finish the ChatGPT login in your browser.\n\n${chalk.dim(login.authUrl)}`, 'ChatGPT Login');
441
+ const waitSpinner = p.spinner();
442
+ waitSpinner.start('Waiting for ChatGPT login to complete...');
443
+ const completed = await client.waitForLoginCompleted(login.loginId, {
444
+ timeoutMs: 5 * 60 * 1000,
445
+ });
446
+ if (!completed.success) {
447
+ waitSpinner.stop('ChatGPT login failed');
448
+ throw new Error(completed.error ?? 'Codex ChatGPT login failed');
449
+ }
450
+ waitSpinner.stop('ChatGPT login complete');
451
+ return await client.readAccount(true);
452
+ }
453
+ async function ensureCodexChatGPTSession(client) {
454
+ const current = await client.readAccount(false);
455
+ if (current.account?.type === 'chatgpt') {
456
+ return current;
457
+ }
458
+ if (current.account) {
459
+ const currentLabel = 'OpenAI API key';
460
+ const shouldSwitch = await p.confirm({
461
+ message: `Codex is currently using ${currentLabel}. Switch to ChatGPT login?`,
462
+ initialValue: true,
463
+ });
464
+ if (p.isCancel(shouldSwitch) || !shouldSwitch) {
465
+ return null;
466
+ }
467
+ await client.logout();
468
+ }
469
+ return await ensureCodexChatGPTLogin(client);
470
+ }
471
+ function getCodexModelOptions(models) {
472
+ const visibleModels = models.filter((model) => !model.hidden);
473
+ const defaultModel = visibleModels.find((model) => model.isDefault) ?? visibleModels[0] ?? null;
474
+ if (!defaultModel) {
475
+ return [];
476
+ }
477
+ const secondaryModels = visibleModels
478
+ .filter((model) => model.model !== defaultModel.model)
479
+ .slice(0, 9);
480
+ return [
481
+ {
482
+ value: defaultModel.model,
483
+ label: defaultModel.displayName,
484
+ hint: `${defaultModel.description || 'Recommended'} (recommended)`,
485
+ },
486
+ ...secondaryModels.map((model) => ({
487
+ value: model.model,
488
+ label: model.displayName,
489
+ hint: model.description || model.model,
490
+ })),
491
+ ];
492
+ }
493
+ /**
494
+ * ChatGPT Login setup flow - authenticate with ChatGPT through Codex, choose a model, save preferences
495
+ *
496
+ * Config storage:
497
+ * - provider: 'openai-compatible'
498
+ * - baseURL: special 'codex://chatgpt' URI resolved at runtime to Codex app-server
499
+ * - model: model ID returned by Codex model/list
500
+ */
501
+ async function handleCodexProviderSetup(options = {}) {
502
+ const exitOnCancel = options.exitOnCancel ?? true;
503
+ const abort = (message, exitCode = 0) => {
504
+ p.cancel(message);
505
+ if (exitOnCancel) {
506
+ process.exit(exitCode);
507
+ }
508
+ return false;
509
+ };
510
+ console.log(chalk.cyan('\nChatGPT Login Setup\n'));
511
+ let client = null;
512
+ try {
513
+ client = await CodexAppServerClient.create();
514
+ const account = await ensureCodexChatGPTSession(client);
515
+ if (!account || account.account?.type !== 'chatgpt') {
516
+ return abort('Setup cancelled');
517
+ }
518
+ p.log.success(`Codex authenticated with ChatGPT as ${account.account.email} (${account.account.planType})`);
519
+ const models = await client.listModels();
520
+ const modelOptions = getCodexModelOptions(models);
521
+ if (modelOptions.length === 0) {
522
+ p.log.error('Codex did not return any available models.');
523
+ return abort('Setup cancelled', 1);
524
+ }
525
+ const model = await p.select({
526
+ message: 'Select a model to start with',
527
+ options: modelOptions,
528
+ });
529
+ if (p.isCancel(model)) {
530
+ return abort('Setup cancelled');
531
+ }
532
+ const selectedModel = model;
533
+ const provider = 'openai-compatible';
534
+ const baseURL = createCodexBaseURL('chatgpt');
535
+ const codexReasoningProfile = getReasoningProfile(provider, selectedModel);
536
+ let reasoningPreset;
537
+ if (codexReasoningProfile.capable) {
538
+ const selectedReasoning = await p.select({
539
+ message: 'Select reasoning variant',
540
+ options: getReasoningVariantSelectOptions(codexReasoningProfile.supportedVariants, codexReasoningProfile.defaultVariant),
541
+ ...(codexReasoningProfile.defaultVariant
542
+ ? { initialValue: codexReasoningProfile.defaultVariant }
543
+ : {}),
544
+ });
545
+ if (p.isCancel(selectedReasoning)) {
546
+ return abort('Setup cancelled');
547
+ }
548
+ if (selectedReasoning !== codexReasoningProfile.defaultVariant) {
549
+ reasoningPreset = selectedReasoning;
550
+ }
551
+ }
552
+ const defaultMode = await selectDefaultMode();
553
+ if (defaultMode === null) {
554
+ return abort('Setup cancelled');
555
+ }
556
+ const preferences = createInitialPreferences({
557
+ provider,
558
+ model: selectedModel,
559
+ baseURL,
560
+ defaultMode,
561
+ setupCompleted: true,
562
+ apiKeyPending: false,
563
+ ...(reasoningPreset ? { reasoning: { variant: reasoningPreset } } : {}),
564
+ });
565
+ await saveGlobalPreferences(preferences);
566
+ capture('dexto_setup', {
567
+ provider,
568
+ model: selectedModel,
569
+ setupMode: 'interactive',
570
+ setupVariant: 'codex-chatgpt',
571
+ defaultMode,
572
+ hasBaseURL: true,
573
+ });
574
+ await showSetupComplete(provider, selectedModel, defaultMode, false, {
575
+ providerLabel: getCodexProviderDisplayName('chatgpt'),
576
+ authLabel: getCodexAuthModeLabel('chatgpt'),
577
+ baseURL,
578
+ });
579
+ return true;
580
+ }
581
+ catch (error) {
582
+ const errorMessage = error instanceof Error ? error.message : String(error);
583
+ p.log.error(`ChatGPT Login setup failed: ${errorMessage}`);
584
+ return abort('Setup cancelled', 1);
585
+ }
586
+ finally {
587
+ if (client) {
588
+ await client.close().catch(() => undefined);
589
+ }
590
+ }
591
+ }
592
+ async function handleCodexChatGPTLoginRefresh(options = {}) {
593
+ const exitOnCancel = options.exitOnCancel ?? true;
594
+ const abort = (message, exitCode = 0) => {
595
+ p.cancel(message);
596
+ if (exitOnCancel) {
597
+ process.exit(exitCode);
598
+ }
599
+ return false;
600
+ };
601
+ console.log(chalk.cyan('\nChatGPT Login\n'));
602
+ let client = null;
603
+ try {
604
+ client = await CodexAppServerClient.create();
605
+ const account = await ensureCodexChatGPTSession(client);
606
+ if (!account || account.account?.type !== 'chatgpt') {
607
+ return abort('ChatGPT login cancelled');
608
+ }
609
+ p.log.success(`Codex authenticated with ChatGPT as ${account.account.email} (${account.account.planType})`);
610
+ return true;
611
+ }
612
+ catch (error) {
613
+ const errorMessage = error instanceof Error ? error.message : String(error);
614
+ p.log.error(`ChatGPT Login failed: ${errorMessage}`);
615
+ return abort('ChatGPT login cancelled', 1);
616
+ }
617
+ finally {
618
+ if (client) {
619
+ await client.close().catch(() => undefined);
620
+ }
621
+ }
622
+ }
411
623
  /**
412
624
  * Dexto setup flow - login if needed, select model, save preferences
413
625
  *
@@ -615,7 +827,7 @@ async function getCreditsBalance() {
615
827
  * Users can go back to previous steps to change their selections.
616
828
  */
617
829
  async function handleInteractiveSetup(_options) {
618
- console.log(chalk.cyan('\n🗿 Dexto Nova Setup\n'));
830
+ console.log(chalk.cyan('\nDexto Setup\n'));
619
831
  p.intro(chalk.cyan("Let's configure your AI agent"));
620
832
  // Initialize wizard state
621
833
  let state = { step: 'setupType' };
@@ -662,12 +874,16 @@ async function wizardStepSetupType(state) {
662
874
  });
663
875
  }
664
876
  options.push({
877
+ value: 'openai-codex',
878
+ label: `${chalk.green('●')} ChatGPT Login`,
879
+ hint: 'Use your ChatGPT account through Codex',
880
+ }, {
665
881
  value: 'quick',
666
- label: `${chalk.green('●')} Quick Start`,
882
+ label: `${chalk.blue('●')} Quick Start`,
667
883
  hint: 'Google Gemini (free) - no account needed',
668
884
  }, {
669
885
  value: 'custom',
670
- label: `${chalk.blue('●')} Custom Setup`,
886
+ label: `${chalk.cyan('●')} Custom Setup`,
671
887
  hint: 'Choose your provider (OpenAI, Anthropic, Ollama, etc.)',
672
888
  });
673
889
  const setupType = await p.select({
@@ -683,6 +899,13 @@ async function wizardStepSetupType(state) {
683
899
  await handleDextoProviderSetup();
684
900
  return { ...state, step: 'complete', quickStartHandled: true };
685
901
  }
902
+ if (setupType === 'openai-codex') {
903
+ const completed = await handleCodexProviderSetup({ exitOnCancel: false });
904
+ if (!completed) {
905
+ return { ...state, step: 'setupType' };
906
+ }
907
+ return { ...state, step: 'complete', quickStartHandled: true };
908
+ }
686
909
  if (setupType === 'quick') {
687
910
  // Quick start bypasses the wizard - handle it directly
688
911
  const result = await handleQuickStart({ onCancel: 'back' });
@@ -1289,7 +1512,17 @@ async function saveWizardPreferences(state) {
1289
1512
  hasBaseURL: Boolean(state.baseURL),
1290
1513
  apiKeySkipped,
1291
1514
  });
1292
- await showSetupComplete(provider, model, defaultMode, apiKeySkipped);
1515
+ const codex = parseCodexBaseURL(state.baseURL);
1516
+ const codexSetupOptions = codex && typeof state.baseURL === 'string'
1517
+ ? {
1518
+ providerLabel: getCodexProviderDisplayName(codex.authMode),
1519
+ authLabel: getCodexAuthModeLabel(codex.authMode),
1520
+ baseURL: state.baseURL,
1521
+ }
1522
+ : {};
1523
+ await showSetupComplete(provider, model, defaultMode, apiKeySkipped, {
1524
+ ...codexSetupOptions,
1525
+ });
1293
1526
  }
1294
1527
  /**
1295
1528
  * Non-interactive setup with CLI options
@@ -1352,10 +1585,14 @@ async function showSettingsMenu() {
1352
1585
  }
1353
1586
  // Show current configuration
1354
1587
  if (currentPrefs) {
1588
+ const codex = parseCodexBaseURL(currentPrefs.llm.baseURL);
1355
1589
  const currentConfig = [
1356
- `Provider: ${chalk.cyan(getProviderDisplayName(currentPrefs.llm.provider))}`,
1590
+ `Provider: ${chalk.cyan(getConfiguredProviderDisplayName(currentPrefs.llm.provider, currentPrefs.llm.baseURL))}`,
1357
1591
  `Model: ${chalk.cyan(currentPrefs.llm.model)}`,
1358
1592
  `Default Mode: ${chalk.cyan(currentPrefs.defaults.defaultMode)}`,
1593
+ ...(codex
1594
+ ? [`Authentication: ${chalk.cyan(getCodexAuthModeLabel(codex.authMode))}`]
1595
+ : []),
1359
1596
  ...(currentPrefs.llm.baseURL
1360
1597
  ? [`Base URL: ${chalk.cyan(currentPrefs.llm.baseURL)}`]
1361
1598
  : []),
@@ -1370,8 +1607,15 @@ async function showSettingsMenu() {
1370
1607
  ].join('\n');
1371
1608
  p.note(currentConfig, 'Current Configuration');
1372
1609
  }
1373
- const currentProviderLabel = currentPrefs?.llm.provider ?? 'not set';
1610
+ const currentProviderLabel = currentPrefs
1611
+ ? getConfiguredProviderDisplayName(currentPrefs.llm.provider, currentPrefs.llm.baseURL)
1612
+ : 'not set';
1374
1613
  const currentModelLabel = currentPrefs?.llm.model || 'not set';
1614
+ const currentCodex = currentPrefs ? parseCodexBaseURL(currentPrefs.llm.baseURL) : null;
1615
+ const authActionLabel = currentCodex ? 'Manage ChatGPT login' : 'Update API key';
1616
+ const authActionHint = currentCodex
1617
+ ? 'Verify or reconnect your ChatGPT login for Codex'
1618
+ : 'Re-enter your API key';
1375
1619
  const options = [
1376
1620
  {
1377
1621
  value: 'model',
@@ -1384,9 +1628,9 @@ async function showSettingsMenu() {
1384
1628
  hint: `Currently: ${currentPrefs?.defaults.defaultMode || 'web'}`,
1385
1629
  },
1386
1630
  {
1387
- value: 'apikey',
1388
- label: 'Update API key',
1389
- hint: 'Re-enter your API key',
1631
+ value: 'auth',
1632
+ label: authActionLabel,
1633
+ hint: authActionHint,
1390
1634
  },
1391
1635
  {
1392
1636
  value: 'reset',
@@ -1431,8 +1675,8 @@ async function showSettingsMenu() {
1431
1675
  case 'credits':
1432
1676
  await openCreditsPage();
1433
1677
  break;
1434
- case 'apikey':
1435
- await updateApiKey(currentPrefs?.llm.provider);
1678
+ case 'auth':
1679
+ await updateApiKey(currentPrefs?.llm.provider, currentPrefs?.llm.baseURL);
1436
1680
  break;
1437
1681
  case 'reset': {
1438
1682
  // Reset exits the menu after completion, but returns to menu if cancelled
@@ -1453,25 +1697,37 @@ async function showSettingsMenu() {
1453
1697
  /**
1454
1698
  * Change model setting (includes provider selection)
1455
1699
  */
1456
- async function changeModel(currentProvider) {
1700
+ async function changeModel(currentProvider, currentBaseURL) {
1457
1701
  let provider = currentProvider ?? null;
1702
+ if (isCodexConfigured(provider ?? undefined, currentBaseURL)) {
1703
+ const completed = await handleCodexProviderSetup({ exitOnCancel: false });
1704
+ if (!completed) {
1705
+ p.log.warn('Model change cancelled');
1706
+ }
1707
+ return;
1708
+ }
1458
1709
  // If no provider specified, show selection
1459
- // When Dexto auth is enabled, show Dexto/Other choice first (matching first-time setup flow)
1460
- if (!provider && isDextoAuthEnabled()) {
1710
+ if (!provider) {
1711
+ const sourceOptions = [];
1712
+ if (isDextoAuthEnabled()) {
1713
+ sourceOptions.push({
1714
+ value: 'dexto-nova',
1715
+ label: `${chalk.magenta('★')} Dexto Nova`,
1716
+ hint: 'All models, one account',
1717
+ });
1718
+ }
1719
+ sourceOptions.push({
1720
+ value: 'openai-codex',
1721
+ label: `${chalk.green('●')} ChatGPT Login`,
1722
+ hint: 'Use your ChatGPT account through Codex',
1723
+ }, {
1724
+ value: 'other',
1725
+ label: `${chalk.blue('●')} Other providers`,
1726
+ hint: 'OpenAI, Anthropic, Gemini, Ollama, etc.',
1727
+ });
1461
1728
  const providerChoice = await p.select({
1462
1729
  message: 'Choose your model source',
1463
- options: [
1464
- {
1465
- value: 'dexto-nova',
1466
- label: `${chalk.magenta('★')} Dexto Nova`,
1467
- hint: 'All models, one account',
1468
- },
1469
- {
1470
- value: 'other',
1471
- label: `${chalk.blue('●')} Other providers`,
1472
- hint: 'OpenAI, Anthropic, Gemini, Ollama, etc.',
1473
- },
1474
- ],
1730
+ options: sourceOptions,
1475
1731
  });
1476
1732
  if (p.isCancel(providerChoice)) {
1477
1733
  p.log.warn('Model change cancelled');
@@ -1485,6 +1741,13 @@ async function changeModel(currentProvider) {
1485
1741
  }
1486
1742
  return;
1487
1743
  }
1744
+ if (providerChoice === 'openai-codex') {
1745
+ const completed = await handleCodexProviderSetup({ exitOnCancel: false });
1746
+ if (!completed) {
1747
+ return;
1748
+ }
1749
+ return;
1750
+ }
1488
1751
  // 'other' - fall through to normal provider selection
1489
1752
  }
1490
1753
  // Get provider if not already set
@@ -1618,15 +1881,22 @@ async function changeDefaultMode() {
1618
1881
  p.log.success(`Default mode changed to ${mode}`);
1619
1882
  }
1620
1883
  /**
1621
- * Update API key for current provider
1884
+ * Update authentication for current provider
1622
1885
  */
1623
- async function updateApiKey(currentProvider) {
1886
+ async function updateApiKey(currentProvider, currentBaseURL) {
1624
1887
  const provider = currentProvider || (await selectProvider());
1625
1888
  // Handle cancellation or back from selectProvider
1626
1889
  if (provider === null || provider === '_back') {
1627
1890
  p.log.warn('API key update cancelled');
1628
1891
  return;
1629
1892
  }
1893
+ if (isCodexConfigured(provider, currentBaseURL)) {
1894
+ const completed = await handleCodexChatGPTLoginRefresh({ exitOnCancel: false });
1895
+ if (!completed) {
1896
+ p.log.warn('ChatGPT login update cancelled');
1897
+ }
1898
+ return;
1899
+ }
1630
1900
  // Handle providers that use non-API-key authentication
1631
1901
  if (provider === 'vertex') {
1632
1902
  p.note(`Google Vertex AI uses Application Default Credentials (ADC).\n\n` +
@@ -1907,9 +2177,10 @@ async function promptForBaseURL(provider) {
1907
2177
  /**
1908
2178
  * Show setup complete message
1909
2179
  */
1910
- async function showSetupComplete(provider, model, defaultMode, apiKeySkipped = false) {
2180
+ async function showSetupComplete(provider, model, defaultMode, apiKeySkipped = false, options = {}) {
1911
2181
  const modeCommand = defaultMode === 'web' ? 'dexto' : `dexto --mode ${defaultMode}`;
1912
2182
  const isLocalProvider = provider === 'local' || provider === 'ollama';
2183
+ const providerLabel = options.providerLabel ?? getConfiguredProviderDisplayName(provider, options.baseURL);
1913
2184
  if (apiKeySkipped) {
1914
2185
  console.log(chalk.rgb(255, 165, 0)('\n⚠️ Setup complete (API key pending)\n'));
1915
2186
  }
@@ -1918,9 +2189,11 @@ async function showSetupComplete(provider, model, defaultMode, apiKeySkipped = f
1918
2189
  }
1919
2190
  const summary = [
1920
2191
  `${chalk.bold('Configuration:')}`,
1921
- ` Provider: ${chalk.cyan(getProviderDisplayName(provider))}`,
2192
+ ` Provider: ${chalk.cyan(providerLabel)}`,
1922
2193
  ` Model: ${chalk.cyan(model)}`,
1923
2194
  ` Mode: ${chalk.cyan(defaultMode)}`,
2195
+ ...(options.authLabel ? [` Authentication: ${chalk.cyan(options.authLabel)}`] : []),
2196
+ ...(options.baseURL ? [` Base URL: ${chalk.cyan(options.baseURL)}`] : []),
1924
2197
  ...(apiKeySkipped
1925
2198
  ? [
1926
2199
  ` API Key: ${chalk.rgb(255, 165, 0)('Not configured')}`,
@@ -1,18 +1,15 @@
1
1
  import { z } from 'zod';
2
- declare const UninstallCommandSchema: z.ZodObject<{
3
- agents: z.ZodArray<z.ZodString, "many">;
4
- all: z.ZodDefault<z.ZodBoolean>;
5
- force: z.ZodDefault<z.ZodBoolean>;
2
+ declare const UninstallCliCommandSchema: z.ZodObject<{
3
+ purge: z.ZodDefault<z.ZodBoolean>;
4
+ dryRun: z.ZodDefault<z.ZodBoolean>;
6
5
  }, "strict", z.ZodTypeAny, {
7
- agents: string[];
8
- force: boolean;
9
- all: boolean;
6
+ dryRun: boolean;
7
+ purge: boolean;
10
8
  }, {
11
- agents: string[];
12
- force?: boolean | undefined;
13
- all?: boolean | undefined;
9
+ dryRun?: boolean | undefined;
10
+ purge?: boolean | undefined;
14
11
  }>;
15
- export type UninstallCommandOptions = z.output<typeof UninstallCommandSchema>;
16
- export declare function handleUninstallCommand(agents: string[], options: Partial<UninstallCommandOptions>): Promise<void>;
12
+ export type UninstallCliCommandOptions = z.output<typeof UninstallCliCommandSchema>;
13
+ export declare function handleUninstallCliCommand(options: Partial<UninstallCliCommandOptions>): Promise<void>;
17
14
  export {};
18
15
  //# sourceMappingURL=uninstall.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/uninstall.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,QAAA,MAAM,sBAAsB;;;;;;;;;;;;EAMf,CAAC;AAEd,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AA+B9E,wBAAsB,sBAAsB,CACxC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC1C,OAAO,CAAC,IAAI,CAAC,CA8Gf"}
1
+ {"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/uninstall.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,QAAA,MAAM,yBAAyB;;;;;;;;;EAKlB,CAAC;AAEd,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAoDpF,wBAAsB,yBAAyB,CAC3C,OAAO,EAAE,OAAO,CAAC,0BAA0B,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAgFf"}