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.
- package/README.md +13 -0
- package/dist/agents/agent-template.yml +1 -1
- package/dist/agents/coding-agent/coding-agent.yml +17 -2
- package/dist/agents/coding-agent/skills/code-review.md +46 -0
- package/dist/agents/explore-agent/explore-agent.yml +2 -0
- package/dist/agents/podcast-agent/podcast-agent.yml +1 -1
- package/dist/analytics/events.d.ts +1 -1
- package/dist/analytics/events.d.ts.map +1 -1
- package/dist/api/server-hono.d.ts.map +1 -1
- package/dist/api/server-hono.js +55 -10
- package/dist/cli/assets/dexto-logo.svg +31 -0
- package/dist/cli/auth/api-client.d.ts +49 -0
- package/dist/cli/auth/api-client.d.ts.map +1 -0
- package/dist/cli/auth/api-client.js +127 -0
- package/dist/cli/auth/constants.d.ts +23 -0
- package/dist/cli/auth/constants.d.ts.map +1 -0
- package/dist/cli/auth/constants.js +24 -0
- package/dist/cli/auth/index.d.ts +5 -0
- package/dist/cli/auth/index.d.ts.map +1 -0
- package/dist/cli/auth/index.js +6 -0
- package/dist/cli/auth/oauth.d.ts +26 -0
- package/dist/cli/auth/oauth.d.ts.map +1 -0
- package/dist/cli/auth/oauth.js +327 -0
- package/dist/cli/auth/service.d.ts +20 -0
- package/dist/cli/auth/service.d.ts.map +1 -0
- package/dist/cli/auth/service.js +147 -0
- package/dist/cli/commands/auth/index.d.ts +4 -0
- package/dist/cli/commands/auth/index.d.ts.map +1 -0
- package/dist/cli/commands/auth/index.js +4 -0
- package/dist/cli/commands/auth/login.d.ts +9 -0
- package/dist/cli/commands/auth/login.d.ts.map +1 -0
- package/dist/cli/commands/auth/login.js +255 -0
- package/dist/cli/commands/auth/logout.d.ts +5 -0
- package/dist/cli/commands/auth/logout.d.ts.map +1 -0
- package/dist/cli/commands/auth/logout.js +51 -0
- package/dist/cli/commands/auth/status.d.ts +2 -0
- package/dist/cli/commands/auth/status.d.ts.map +1 -0
- package/dist/cli/commands/auth/status.js +22 -0
- package/dist/cli/commands/billing/index.d.ts +2 -0
- package/dist/cli/commands/billing/index.d.ts.map +1 -0
- package/dist/cli/commands/billing/index.js +2 -0
- package/dist/cli/commands/billing/status.d.ts +6 -0
- package/dist/cli/commands/billing/status.d.ts.map +1 -0
- package/dist/cli/commands/billing/status.js +60 -0
- package/dist/cli/commands/index.d.ts +4 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +9 -0
- package/dist/cli/commands/interactive-commands/auth/index.d.ts +12 -0
- package/dist/cli/commands/interactive-commands/auth/index.d.ts.map +1 -0
- package/dist/cli/commands/interactive-commands/auth/index.js +20 -0
- package/dist/cli/commands/interactive-commands/command-parser.d.ts +5 -0
- package/dist/cli/commands/interactive-commands/command-parser.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/command-parser.js +6 -0
- package/dist/cli/commands/interactive-commands/commands.d.ts +1 -0
- package/dist/cli/commands/interactive-commands/commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/commands.js +10 -0
- package/dist/cli/commands/interactive-commands/export/index.d.ts +13 -0
- package/dist/cli/commands/interactive-commands/export/index.d.ts.map +1 -0
- package/dist/cli/commands/interactive-commands/export/index.js +21 -0
- package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/general-commands.js +1 -0
- package/dist/cli/commands/interactive-commands/mcp/index.d.ts +2 -2
- package/dist/cli/commands/interactive-commands/mcp/index.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/mcp/index.js +4 -7
- package/dist/cli/commands/interactive-commands/model/index.d.ts +2 -2
- package/dist/cli/commands/interactive-commands/model/index.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/model/index.js +4 -7
- package/dist/cli/commands/interactive-commands/plugin/index.d.ts +13 -0
- package/dist/cli/commands/interactive-commands/plugin/index.d.ts.map +1 -0
- package/dist/cli/commands/interactive-commands/plugin/index.js +18 -0
- package/dist/cli/commands/interactive-commands/prompt-commands.d.ts +3 -1
- package/dist/cli/commands/interactive-commands/prompt-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/prompt-commands.js +72 -36
- package/dist/cli/commands/interactive-commands/system/system-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/system/system-commands.js +2 -3
- package/dist/cli/commands/plugin.d.ts +161 -0
- package/dist/cli/commands/plugin.d.ts.map +1 -0
- package/dist/cli/commands/plugin.js +376 -0
- package/dist/cli/commands/setup.d.ts +9 -9
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +325 -37
- package/dist/cli/commands/sync-agents.d.ts +44 -0
- package/dist/cli/commands/sync-agents.d.ts.map +1 -0
- package/dist/cli/commands/sync-agents.js +483 -0
- package/dist/cli/ink-cli/InkCLIRefactored.d.ts +14 -1
- package/dist/cli/ink-cli/InkCLIRefactored.d.ts.map +1 -1
- package/dist/cli/ink-cli/InkCLIRefactored.js +8 -2
- package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts +1 -1
- package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/ApprovalPrompt.js +80 -12
- package/dist/cli/ink-cli/components/Footer.d.ts +2 -1
- package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/Footer.js +6 -2
- package/dist/cli/ink-cli/components/SlashCommandAutocomplete.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/SlashCommandAutocomplete.js +15 -7
- package/dist/cli/ink-cli/components/StatusBar.d.ts +9 -1
- package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/StatusBar.js +17 -5
- package/dist/cli/ink-cli/components/TodoPanel.d.ts +11 -8
- package/dist/cli/ink-cli/components/TodoPanel.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/TodoPanel.js +38 -36
- package/dist/cli/ink-cli/components/chat/Header.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/Header.js +1 -1
- package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/MessageItem.js +14 -1
- package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.js +1 -1
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +16 -4
- package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/StaticCLI.js +4 -1
- package/dist/cli/ink-cli/components/overlays/ExportWizard.d.ts +22 -0
- package/dist/cli/ink-cli/components/overlays/ExportWizard.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/ExportWizard.js +308 -0
- package/dist/cli/ink-cli/components/overlays/LogLevelSelector.d.ts +1 -0
- package/dist/cli/ink-cli/components/overlays/LogLevelSelector.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/LogLevelSelector.js +31 -20
- package/dist/cli/ink-cli/components/overlays/MarketplaceAddPrompt.d.ts +20 -0
- package/dist/cli/ink-cli/components/overlays/MarketplaceAddPrompt.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/MarketplaceAddPrompt.js +81 -0
- package/dist/cli/ink-cli/components/overlays/MarketplaceBrowser.d.ts +31 -0
- package/dist/cli/ink-cli/components/overlays/MarketplaceBrowser.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/MarketplaceBrowser.js +297 -0
- package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.js +7 -1
- package/dist/cli/ink-cli/components/overlays/McpServerActions.d.ts +1 -1
- package/dist/cli/ink-cli/components/overlays/McpServerActions.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/McpServerActions.js +9 -0
- package/dist/cli/ink-cli/components/overlays/McpServerList.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/McpServerList.js +9 -2
- package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.js +15 -2
- package/dist/cli/ink-cli/components/overlays/PluginActions.d.ts +27 -0
- package/dist/cli/ink-cli/components/overlays/PluginActions.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/PluginActions.js +66 -0
- package/dist/cli/ink-cli/components/overlays/PluginList.d.ts +21 -0
- package/dist/cli/ink-cli/components/overlays/PluginList.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/PluginList.js +70 -0
- package/dist/cli/ink-cli/components/overlays/PluginManager.d.ts +21 -0
- package/dist/cli/ink-cli/components/overlays/PluginManager.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/PluginManager.js +63 -0
- package/dist/cli/ink-cli/components/overlays/PromptList.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/PromptList.js +4 -1
- package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts +2 -1
- package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.js +61 -2
- package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.d.ts +4 -2
- package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.js +4 -4
- package/dist/cli/ink-cli/constants/tips.js +2 -2
- package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/InputContainer.js +31 -3
- package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/OverlayContainer.js +260 -11
- package/dist/cli/ink-cli/hooks/index.d.ts +1 -0
- package/dist/cli/ink-cli/hooks/index.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/index.js +1 -0
- package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useCLIState.js +3 -0
- package/dist/cli/ink-cli/hooks/useGitBranch.d.ts +13 -0
- package/dist/cli/ink-cli/hooks/useGitBranch.d.ts.map +1 -0
- package/dist/cli/ink-cli/hooks/useGitBranch.js +35 -0
- package/dist/cli/ink-cli/hooks/useInputOrchestrator.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useInputOrchestrator.js +50 -6
- package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
- package/dist/cli/ink-cli/services/processStream.js +42 -10
- package/dist/cli/ink-cli/state/initialState.d.ts.map +1 -1
- package/dist/cli/ink-cli/state/initialState.js +3 -0
- package/dist/cli/ink-cli/state/types.d.ts +16 -1
- package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/commandOverlays.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/commandOverlays.js +2 -0
- package/dist/cli/ink-cli/utils/messageFormatting.d.ts +14 -1
- package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/messageFormatting.js +68 -8
- package/dist/cli/ink-cli/utils/toolUtils.d.ts +11 -0
- package/dist/cli/ink-cli/utils/toolUtils.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/toolUtils.js +17 -0
- package/dist/cli/mcp/index.d.ts +8 -0
- package/dist/cli/mcp/index.d.ts.map +1 -0
- package/dist/cli/mcp/index.js +7 -0
- package/dist/cli/mcp/oauth-factory.d.ts +6 -0
- package/dist/cli/mcp/oauth-factory.d.ts.map +1 -0
- package/dist/cli/mcp/oauth-factory.js +25 -0
- package/dist/cli/mcp/oauth-provider.d.ts +10 -0
- package/dist/cli/mcp/oauth-provider.d.ts.map +1 -0
- package/dist/cli/mcp/oauth-provider.js +77 -0
- package/dist/cli/mcp/oauth-redirect.d.ts +3 -0
- package/dist/cli/mcp/oauth-redirect.d.ts.map +1 -0
- package/dist/cli/mcp/oauth-redirect.js +4 -0
- package/dist/cli/mcp/oauth-server.d.ts +2 -0
- package/dist/cli/mcp/oauth-server.d.ts.map +1 -0
- package/dist/cli/mcp/oauth-server.js +70 -0
- package/dist/cli/mcp/oauth-store.d.ts +10 -0
- package/dist/cli/mcp/oauth-store.d.ts.map +1 -0
- package/dist/cli/mcp/oauth-store.js +27 -0
- package/dist/cli/mcp/oauth-ui.d.ts +2 -0
- package/dist/cli/mcp/oauth-ui.d.ts.map +1 -0
- package/dist/cli/mcp/oauth-ui.js +12 -0
- package/dist/cli/mcp/oauth-utils.d.ts +2 -0
- package/dist/cli/mcp/oauth-utils.d.ts.map +1 -0
- package/dist/cli/mcp/oauth-utils.js +17 -0
- package/dist/cli/utils/api-key-setup.d.ts.map +1 -1
- package/dist/cli/utils/api-key-setup.js +13 -90
- package/dist/cli/utils/api-key-verification.d.ts.map +1 -1
- package/dist/cli/utils/api-key-verification.js +36 -0
- package/dist/cli/utils/config-validation.d.ts +3 -1
- package/dist/cli/utils/config-validation.d.ts.map +1 -1
- package/dist/cli/utils/config-validation.js +42 -19
- package/dist/cli/utils/dexto-auth-check.d.ts +53 -0
- package/dist/cli/utils/dexto-auth-check.d.ts.map +1 -0
- package/dist/cli/utils/dexto-auth-check.js +104 -0
- package/dist/cli/utils/dexto-setup.d.ts +8 -0
- package/dist/cli/utils/dexto-setup.d.ts.map +1 -0
- package/dist/cli/utils/dexto-setup.js +17 -0
- package/dist/cli/utils/options.d.ts.map +1 -1
- package/dist/cli/utils/options.js +5 -1
- package/dist/cli/utils/provider-setup.d.ts +4 -0
- package/dist/cli/utils/provider-setup.d.ts.map +1 -1
- package/dist/cli/utils/provider-setup.js +20 -0
- package/dist/cli/utils/version-check.d.ts +45 -0
- package/dist/cli/utils/version-check.d.ts.map +1 -0
- package/dist/cli/utils/version-check.js +195 -0
- package/dist/config/cli-overrides.d.ts +17 -8
- package/dist/config/cli-overrides.d.ts.map +1 -1
- package/dist/config/cli-overrides.js +36 -22
- package/dist/config/effective-llm.d.ts +123 -0
- package/dist/config/effective-llm.d.ts.map +1 -0
- package/dist/config/effective-llm.js +171 -0
- package/dist/index.js +451 -126
- package/dist/webui/assets/index-C9JXwpvo.css +1 -0
- package/dist/webui/assets/{index-DVQWNLpT.js → index-Dl3mj53P.js} +217 -217
- package/dist/webui/index.html +2 -2
- package/package.json +9 -8
- package/dist/webui/assets/index-BglIVTSG.css +0 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
import { URL } from 'node:url';
|
|
3
|
+
import { ensurePortAvailable } from './oauth-utils.js';
|
|
4
|
+
function escapeHtml(value) {
|
|
5
|
+
return value
|
|
6
|
+
.replace(/&/g, '&')
|
|
7
|
+
.replace(/</g, '<')
|
|
8
|
+
.replace(/>/g, '>')
|
|
9
|
+
.replace(/"/g, '"')
|
|
10
|
+
.replace(/'/g, ''');
|
|
11
|
+
}
|
|
12
|
+
export async function createMcpCallbackServer(redirectUrl) {
|
|
13
|
+
const parsed = new URL(redirectUrl);
|
|
14
|
+
const port = Number(parsed.port || 8080);
|
|
15
|
+
if (!Number.isFinite(port) || port <= 0) {
|
|
16
|
+
throw new Error(`Invalid redirect port: ${parsed.port}`);
|
|
17
|
+
}
|
|
18
|
+
await ensurePortAvailable(port);
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const server = createServer((req, res) => {
|
|
21
|
+
if (!req.url) {
|
|
22
|
+
res.writeHead(400);
|
|
23
|
+
res.end('Bad Request');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const requestUrl = new URL(req.url, redirectUrl);
|
|
27
|
+
const code = requestUrl.searchParams.get('code');
|
|
28
|
+
const error = requestUrl.searchParams.get('error');
|
|
29
|
+
const errorDescription = requestUrl.searchParams.get('error_description');
|
|
30
|
+
if (code) {
|
|
31
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
32
|
+
res.end(`
|
|
33
|
+
<html>
|
|
34
|
+
<body>
|
|
35
|
+
<h1>Authorization Successful</h1>
|
|
36
|
+
<p>You can close this window and return to your terminal.</p>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
|
39
|
+
`);
|
|
40
|
+
resolve(code);
|
|
41
|
+
setTimeout(() => server.close(), 3000);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (error) {
|
|
45
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
46
|
+
res.end(`
|
|
47
|
+
<html>
|
|
48
|
+
<body>
|
|
49
|
+
<h1>Authorization Failed</h1>
|
|
50
|
+
<p>Error: ${escapeHtml(error)}</p>
|
|
51
|
+
${errorDescription ? `<p>${escapeHtml(errorDescription)}</p>` : ''}
|
|
52
|
+
</body>
|
|
53
|
+
</html>
|
|
54
|
+
`);
|
|
55
|
+
reject(new Error(`OAuth authorization failed: ${error}${errorDescription ? ` (${errorDescription})` : ''}`));
|
|
56
|
+
setTimeout(() => server.close(), 3000);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
res.writeHead(400);
|
|
60
|
+
res.end('Missing authorization code');
|
|
61
|
+
});
|
|
62
|
+
server.on('error', (err) => {
|
|
63
|
+
reject(err);
|
|
64
|
+
server.close();
|
|
65
|
+
});
|
|
66
|
+
server.listen(port, () => {
|
|
67
|
+
console.log(`🔐 Awaiting MCP OAuth callback on ${redirectUrl}`);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { OAuthTokens, OAuthClientInformationMixed } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
2
|
+
export type McpAuthStore = {
|
|
3
|
+
tokens?: OAuthTokens | undefined;
|
|
4
|
+
clientInformation?: OAuthClientInformationMixed | undefined;
|
|
5
|
+
codeVerifier?: string | undefined;
|
|
6
|
+
};
|
|
7
|
+
export declare function loadMcpAuthStore(serverId: string): Promise<McpAuthStore>;
|
|
8
|
+
export declare function saveMcpAuthStore(serverId: string, store: McpAuthStore): Promise<void>;
|
|
9
|
+
export declare function getMcpAuthStorePath(serverId: string): string;
|
|
10
|
+
//# sourceMappingURL=oauth-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-store.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/oauth-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,WAAW,EACX,2BAA2B,EAC9B,MAAM,0CAA0C,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG;IACvB,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,iBAAiB,CAAC,EAAE,2BAA2B,GAAG,SAAS,CAAC;IAC5D,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAW9E;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3F;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { getDextoPath } from '@dexto/core';
|
|
4
|
+
export async function loadMcpAuthStore(serverId) {
|
|
5
|
+
const filePath = getMcpAuthStorePath(serverId);
|
|
6
|
+
try {
|
|
7
|
+
const data = await fs.readFile(filePath, 'utf8');
|
|
8
|
+
return JSON.parse(data);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
if (error.code === 'ENOENT') {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
throw error;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export async function saveMcpAuthStore(serverId, store) {
|
|
18
|
+
const filePath = getMcpAuthStorePath(serverId);
|
|
19
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
20
|
+
await fs.writeFile(filePath, JSON.stringify(store, null, 2));
|
|
21
|
+
}
|
|
22
|
+
export function getMcpAuthStorePath(serverId) {
|
|
23
|
+
return getDextoPath('mcp-auth', `${sanitizeServerId(serverId)}.json`);
|
|
24
|
+
}
|
|
25
|
+
function sanitizeServerId(serverId) {
|
|
26
|
+
return serverId.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-ui.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/oauth-ui.ts"],"names":[],"mappings":"AAEA,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU5D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
export async function openAuthUrl(url) {
|
|
3
|
+
console.log(chalk.cyan('🌐 Opening browser for MCP authentication...'));
|
|
4
|
+
try {
|
|
5
|
+
const { default: open } = await import('open');
|
|
6
|
+
await open(url, { wait: false });
|
|
7
|
+
console.log(chalk.green('✅ Browser opened'));
|
|
8
|
+
}
|
|
9
|
+
catch (_error) {
|
|
10
|
+
console.log(chalk.yellow(`💡 Please open manually: ${url}`));
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-utils.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/oauth-utils.ts"],"names":[],"mappings":"AAEA,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBrE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
export async function ensurePortAvailable(port) {
|
|
3
|
+
await new Promise((resolve, reject) => {
|
|
4
|
+
const server = createServer();
|
|
5
|
+
server.listen(port, () => {
|
|
6
|
+
server.close(() => resolve());
|
|
7
|
+
});
|
|
8
|
+
server.on('error', (err) => {
|
|
9
|
+
if (err.code === 'EADDRINUSE') {
|
|
10
|
+
reject(new Error(`Port ${port} is already in use. Please close the application using it and try again.`));
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
reject(err);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-key-setup.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/api-key-setup.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"api-key-setup.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/api-key-setup.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAc/C,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CACxC,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE;IACL,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CACb,GACP,OAAO,CAAC,iBAAiB,CAAC,CAmK5B;AA8GD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAGlE;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACrC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CACxC,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,MAAM,GACd,OAAO,CAAC,wBAAwB,CAAC,CAkEnC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACpC,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,QAAQ,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAC7C,aAAa,EAAE,WAAW,EAC1B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,WAAW,EACzB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,uBAAuB,CAAC,CAiGlC"}
|
|
@@ -4,7 +4,7 @@ import chalk from 'chalk';
|
|
|
4
4
|
import { logger, getExecutionContext } from '@dexto/core';
|
|
5
5
|
import { saveProviderApiKey } from '@dexto/agent-management';
|
|
6
6
|
import { applyLayeredEnvironmentLoading } from '../../utils/env.js';
|
|
7
|
-
import { getProviderDisplayName, validateApiKeyFormat, getProviderInstructions, openApiKeyUrl, getProviderInfo, getProviderEnvVar,
|
|
7
|
+
import { getProviderDisplayName, validateApiKeyFormat, getProviderInstructions, openApiKeyUrl, getProviderInfo, getProviderEnvVar, } from './provider-setup.js';
|
|
8
8
|
import { verifyApiKey } from './api-key-verification.js';
|
|
9
9
|
/**
|
|
10
10
|
* Interactively prompts the user to set up an API key for a specific provider.
|
|
@@ -32,25 +32,20 @@ export async function interactiveApiKeySetup(provider, options = {}) {
|
|
|
32
32
|
? [
|
|
33
33
|
{
|
|
34
34
|
value: 'open-browser',
|
|
35
|
-
label: '
|
|
36
|
-
hint: '
|
|
35
|
+
label: `${chalk.green('→')} Get API key (opens browser)`,
|
|
36
|
+
hint: "We'll wait while you grab one",
|
|
37
37
|
},
|
|
38
38
|
]
|
|
39
39
|
: []),
|
|
40
40
|
{
|
|
41
41
|
value: 'setup',
|
|
42
|
-
label:
|
|
43
|
-
hint: '
|
|
42
|
+
label: `${chalk.cyan('●')} Paste existing key`,
|
|
43
|
+
hint: 'I already have an API key',
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
value: 'skip',
|
|
47
|
-
label: '
|
|
48
|
-
hint: 'Continue without
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
value: 'manual',
|
|
52
|
-
label: 'View manual instructions',
|
|
53
|
-
hint: 'See how to set up manually',
|
|
47
|
+
label: `${chalk.gray('○')} Set up later`,
|
|
48
|
+
hint: 'Continue without key for now',
|
|
54
49
|
},
|
|
55
50
|
];
|
|
56
51
|
const action = await p.select({
|
|
@@ -64,13 +59,12 @@ export async function interactiveApiKeySetup(provider, options = {}) {
|
|
|
64
59
|
return { success: false, cancelled: true };
|
|
65
60
|
}
|
|
66
61
|
if (action === 'skip') {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
p.log.info('You can configure your API key later with: dexto setup');
|
|
62
|
+
const envVar = getProviderEnvVar(provider);
|
|
63
|
+
p.note(`You can configure your API key later:\n\n` +
|
|
64
|
+
`${chalk.cyan('Option 1:')} Run ${chalk.bold('dexto setup')}\n\n` +
|
|
65
|
+
`${chalk.cyan('Option 2:')} Set environment variable manually:\n` +
|
|
66
|
+
` ${chalk.dim(`export ${envVar}=your-key-here`)}\n` +
|
|
67
|
+
` ${chalk.dim('Add to ~/.bashrc or ~/.zshrc to persist')}`, 'Setup Later');
|
|
74
68
|
return { success: true, skipped: true };
|
|
75
69
|
}
|
|
76
70
|
// Open browser if requested
|
|
@@ -252,77 +246,6 @@ function showManualSaveInstructions(provider, apiKey) {
|
|
|
252
246
|
];
|
|
253
247
|
p.note(instructions.join('\n'), chalk.rgb(255, 165, 0)('Manual Setup Required'));
|
|
254
248
|
}
|
|
255
|
-
/**
|
|
256
|
-
* Shows manual setup instructions to the user
|
|
257
|
-
*/
|
|
258
|
-
function showManualSetupInstructions(provider) {
|
|
259
|
-
const envVar = getProviderEnvVar(provider);
|
|
260
|
-
const providerInfo = getProviderInfo(provider);
|
|
261
|
-
const envInstructions = getExecutionContext() === 'global-cli'
|
|
262
|
-
? [
|
|
263
|
-
`${chalk.bold('2. Save your API key:')}`,
|
|
264
|
-
` ${chalk.gray('Option A:')} Run ${chalk.cyan('dexto setup')} (interactive)`,
|
|
265
|
-
` ${chalk.gray('Option B:')} Create ${chalk.cyan('~/.dexto/.env')} with:`,
|
|
266
|
-
` ${chalk.rgb(255, 165, 0)(`${envVar}=your_api_key_here`)}`,
|
|
267
|
-
]
|
|
268
|
-
: [
|
|
269
|
-
`${chalk.bold('2. Save your API key:')}`,
|
|
270
|
-
` Create ${chalk.cyan('.env')} in your project with:`,
|
|
271
|
-
` ${chalk.rgb(255, 165, 0)(`${envVar}=your_api_key_here`)}`,
|
|
272
|
-
];
|
|
273
|
-
// Build provider URLs list dynamically from registry
|
|
274
|
-
const providerUrls = [];
|
|
275
|
-
// Add current provider first if it has an API key URL
|
|
276
|
-
if (providerInfo?.apiKeyUrl) {
|
|
277
|
-
providerUrls.push(` ${chalk.cyan('→')} ${chalk.cyan(getProviderDisplayName(provider))}: ${providerInfo.apiKeyUrl}`);
|
|
278
|
-
providerUrls.push(''); // Add spacing
|
|
279
|
-
}
|
|
280
|
-
// Add recommended/popular providers with API keys
|
|
281
|
-
const popularProviders = [
|
|
282
|
-
{ provider: 'google', color: chalk.green }, // Free
|
|
283
|
-
{ provider: 'groq', color: chalk.green }, // Free
|
|
284
|
-
{ provider: 'openai', color: chalk.blue },
|
|
285
|
-
{ provider: 'anthropic', color: chalk.blue },
|
|
286
|
-
{ provider: 'xai', color: chalk.blue },
|
|
287
|
-
{ provider: 'cohere', color: chalk.blue },
|
|
288
|
-
];
|
|
289
|
-
for (const { provider: p, color } of popularProviders) {
|
|
290
|
-
const info = PROVIDER_REGISTRY[p];
|
|
291
|
-
if (info?.apiKeyUrl && p !== provider) {
|
|
292
|
-
// Don't duplicate current provider
|
|
293
|
-
const freeTag = info.free ? ' (Free)' : '';
|
|
294
|
-
providerUrls.push(` ${color('●')} ${color(info.label + freeTag)}: ${info.apiKeyUrl}`);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
// Add gateway providers
|
|
298
|
-
const gatewayProviders = ['openrouter', 'glama'];
|
|
299
|
-
for (const p of gatewayProviders) {
|
|
300
|
-
const info = PROVIDER_REGISTRY[p];
|
|
301
|
-
if (info?.apiKeyUrl && p !== provider) {
|
|
302
|
-
providerUrls.push(` ${chalk.rgb(255, 165, 0)('●')} ${chalk.rgb(255, 165, 0)(info.label)} (Gateway): ${info.apiKeyUrl}`);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
// Add enterprise providers
|
|
306
|
-
const enterpriseProviders = ['vertex', 'bedrock'];
|
|
307
|
-
for (const p of enterpriseProviders) {
|
|
308
|
-
const info = PROVIDER_REGISTRY[p];
|
|
309
|
-
if (info?.apiKeyUrl && p !== provider) {
|
|
310
|
-
providerUrls.push(` ${chalk.cyan('●')} ${chalk.cyan(info.label)} (Enterprise): ${info.apiKeyUrl}`);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
const instructions = [
|
|
314
|
-
`${chalk.bold('1. Get an API key from your provider:')}`,
|
|
315
|
-
...providerUrls,
|
|
316
|
-
``,
|
|
317
|
-
...envInstructions,
|
|
318
|
-
``,
|
|
319
|
-
`${chalk.bold('3. Run dexto again:')}`,
|
|
320
|
-
` ${chalk.cyan('dexto')} or ${chalk.cyan('npx dexto')}`,
|
|
321
|
-
``,
|
|
322
|
-
`${chalk.gray('💡 Tip: Start with Google Gemini or Groq for a free experience!')}`,
|
|
323
|
-
].join('\n');
|
|
324
|
-
p.note(instructions, chalk.bold('Manual Setup Instructions'));
|
|
325
|
-
}
|
|
326
249
|
/**
|
|
327
250
|
* Quick check if an API key is already configured for a provider
|
|
328
251
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-key-verification.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/api-key-verification.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAC9B,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"api-key-verification.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/api-key-verification.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAC9B,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,CAAC,CA0C7B"}
|
|
@@ -28,6 +28,10 @@ export async function verifyApiKey(provider, apiKey, _model) {
|
|
|
28
28
|
return await verifyOpenRouter(apiKey);
|
|
29
29
|
case 'glama':
|
|
30
30
|
return await verifyGlama(apiKey);
|
|
31
|
+
case 'minimax':
|
|
32
|
+
return await verifyMiniMax(apiKey);
|
|
33
|
+
case 'glm':
|
|
34
|
+
return await verifyGLM(apiKey);
|
|
31
35
|
case 'openai-compatible':
|
|
32
36
|
case 'litellm':
|
|
33
37
|
// For custom endpoints, we can't verify without a baseURL
|
|
@@ -184,6 +188,38 @@ async function verifyGlama(apiKey) {
|
|
|
184
188
|
const error = await parseErrorResponse(response);
|
|
185
189
|
return { success: false, error };
|
|
186
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Verify MiniMax API key using the OpenAI-compatible models endpoint
|
|
193
|
+
*/
|
|
194
|
+
async function verifyMiniMax(apiKey) {
|
|
195
|
+
const response = await fetch('https://api.minimax.chat/v1/models', {
|
|
196
|
+
method: 'GET',
|
|
197
|
+
headers: {
|
|
198
|
+
Authorization: `Bearer ${apiKey}`,
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
if (response.ok) {
|
|
202
|
+
return { success: true, modelUsed: 'models-list' };
|
|
203
|
+
}
|
|
204
|
+
const error = await parseErrorResponse(response);
|
|
205
|
+
return { success: false, error };
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Verify GLM (Zhipu) API key using the OpenAI-compatible models endpoint
|
|
209
|
+
*/
|
|
210
|
+
async function verifyGLM(apiKey) {
|
|
211
|
+
const response = await fetch('https://open.bigmodel.cn/api/paas/v4/models', {
|
|
212
|
+
method: 'GET',
|
|
213
|
+
headers: {
|
|
214
|
+
Authorization: `Bearer ${apiKey}`,
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
if (response.ok) {
|
|
218
|
+
return { success: true, modelUsed: 'models-list' };
|
|
219
|
+
}
|
|
220
|
+
const error = await parseErrorResponse(response);
|
|
221
|
+
return { success: false, error };
|
|
222
|
+
}
|
|
187
223
|
/**
|
|
188
224
|
* Parse error response from provider API
|
|
189
225
|
*/
|
|
@@ -19,7 +19,9 @@ export interface ValidationResult {
|
|
|
19
19
|
* @param validationOptions.strict - When true (default), enforces API key requirements.
|
|
20
20
|
* When false, allows missing credentials for interactive config.
|
|
21
21
|
*/
|
|
22
|
-
export declare function validateAgentConfig(config: AgentConfig, interactive?: boolean, validationOptions?: LLMValidationOptions
|
|
22
|
+
export declare function validateAgentConfig(config: AgentConfig, interactive?: boolean, validationOptions?: LLMValidationOptions & {
|
|
23
|
+
agentPath?: string;
|
|
24
|
+
}): Promise<ValidationResult>;
|
|
23
25
|
/**
|
|
24
26
|
* Legacy function for backwards compatibility
|
|
25
27
|
* @deprecated Use validateAgentConfig with result handling instead
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-validation.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/config-validation.ts"],"names":[],"mappings":"AAGA,OAAO,EAGH,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAC5B,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"config-validation.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/config-validation.ts"],"names":[],"mappings":"AAGA,OAAO,EAGH,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAC5B,MAAM,aAAa,CAAC;AAYrB,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,WAAW,EACnB,WAAW,GAAE,OAAe,EAC5B,iBAAiB,CAAC,EAAE,oBAAoB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClE,OAAO,CAAC,gBAAgB,CAAC,CAyC3B;AAkbD;;;GAGG;AACH,wBAAsB,yBAAyB,CAC3C,MAAM,EAAE,WAAW,EACnB,WAAW,GAAE,OAAe,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAgC/B"}
|
|
@@ -5,6 +5,7 @@ import { interactiveApiKeySetup } from './api-key-setup.js';
|
|
|
5
5
|
import { LLMErrorCode } from '@dexto/core';
|
|
6
6
|
import { logger } from '@dexto/core';
|
|
7
7
|
import { getGlobalPreferencesPath, loadGlobalPreferences, saveGlobalPreferences, } from '@dexto/agent-management';
|
|
8
|
+
import { handleSyncAgentsCommand } from '../commands/sync-agents.js';
|
|
8
9
|
/**
|
|
9
10
|
* Validates agent config with optional interactive fixes for user experience.
|
|
10
11
|
* Uses schema parsing to detect API key issues and provides targeted setup.
|
|
@@ -51,7 +52,7 @@ export async function validateAgentConfig(config, interactive = false, validatio
|
|
|
51
52
|
return await handleBaseURLError(baseURLError.provider, config, errors, validationOptions);
|
|
52
53
|
}
|
|
53
54
|
// Other validation errors - show options
|
|
54
|
-
return await handleOtherErrors(errors);
|
|
55
|
+
return await handleOtherErrors(errors, validationOptions);
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
58
|
* Handle API key validation errors interactively
|
|
@@ -92,7 +93,7 @@ async function handleApiKeyError(provider, config, errors, validationOptions) {
|
|
|
92
93
|
return { success: false, errors, skipped: true };
|
|
93
94
|
}
|
|
94
95
|
if (action === 'edit') {
|
|
95
|
-
showManualEditInstructions();
|
|
96
|
+
showManualEditInstructions(undefined);
|
|
96
97
|
return { success: false, errors, skipped: true };
|
|
97
98
|
}
|
|
98
99
|
// 'skip' - continue anyway
|
|
@@ -154,7 +155,7 @@ async function handleBaseURLError(provider, config, errors, validationOptions) {
|
|
|
154
155
|
return { success: false, errors, skipped: true };
|
|
155
156
|
}
|
|
156
157
|
if (action === 'edit') {
|
|
157
|
-
showManualEditInstructions();
|
|
158
|
+
showManualEditInstructions(undefined);
|
|
158
159
|
return { success: false, errors, skipped: true };
|
|
159
160
|
}
|
|
160
161
|
// 'skip' - continue anyway
|
|
@@ -228,7 +229,7 @@ async function interactiveBaseURLSetup(provider, existingBaseURL) {
|
|
|
228
229
|
/**
|
|
229
230
|
* Handle non-API-key validation errors interactively
|
|
230
231
|
*/
|
|
231
|
-
async function handleOtherErrors(errors) {
|
|
232
|
+
async function handleOtherErrors(errors, validationOptions) {
|
|
232
233
|
console.log(chalk.rgb(255, 165, 0)('\n⚠️ Configuration issues detected:\n'));
|
|
233
234
|
for (const error of errors) {
|
|
234
235
|
console.log(chalk.red(` • ${error}`));
|
|
@@ -237,6 +238,11 @@ async function handleOtherErrors(errors) {
|
|
|
237
238
|
const action = await p.select({
|
|
238
239
|
message: 'How would you like to proceed?',
|
|
239
240
|
options: [
|
|
241
|
+
{
|
|
242
|
+
value: 'sync',
|
|
243
|
+
label: 'Sync agent config',
|
|
244
|
+
hint: 'Update from bundled registry (recommended)',
|
|
245
|
+
},
|
|
240
246
|
{
|
|
241
247
|
value: 'skip',
|
|
242
248
|
label: 'Continue anyway',
|
|
@@ -247,23 +253,27 @@ async function handleOtherErrors(errors) {
|
|
|
247
253
|
label: 'Edit configuration manually',
|
|
248
254
|
hint: 'Show file path and instructions',
|
|
249
255
|
},
|
|
250
|
-
{
|
|
251
|
-
value: 'setup',
|
|
252
|
-
label: 'Run setup again',
|
|
253
|
-
hint: 'Reconfigure from scratch',
|
|
254
|
-
},
|
|
255
256
|
],
|
|
256
257
|
});
|
|
257
258
|
if (p.isCancel(action)) {
|
|
258
259
|
showNextSteps();
|
|
259
260
|
return { success: false, errors, skipped: true };
|
|
260
261
|
}
|
|
261
|
-
if (action === '
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
if (action === 'sync') {
|
|
263
|
+
try {
|
|
264
|
+
// Run sync-agents to update the agent config
|
|
265
|
+
await handleSyncAgentsCommand({ force: true, quiet: false });
|
|
266
|
+
// Exit after sync - user needs to restart dexto
|
|
267
|
+
p.outro(chalk.gray('Run dexto to start Dexto'));
|
|
268
|
+
process.exit(0);
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
p.log.error(`Failed to sync agent: ${error instanceof Error ? error.message : String(error)}`);
|
|
272
|
+
return { success: false, errors, skipped: true };
|
|
273
|
+
}
|
|
264
274
|
}
|
|
265
|
-
if (action === '
|
|
266
|
-
|
|
275
|
+
if (action === 'edit') {
|
|
276
|
+
showManualEditInstructions(validationOptions?.agentPath);
|
|
267
277
|
return { success: false, errors, skipped: true };
|
|
268
278
|
}
|
|
269
279
|
// 'skip' - continue anyway
|
|
@@ -293,19 +303,32 @@ function showNextSteps() {
|
|
|
293
303
|
/**
|
|
294
304
|
* Show manual edit instructions
|
|
295
305
|
*/
|
|
296
|
-
function showManualEditInstructions() {
|
|
306
|
+
function showManualEditInstructions(agentPath) {
|
|
297
307
|
const prefsPath = getGlobalPreferencesPath();
|
|
308
|
+
const configPaths = [` ${chalk.cyan('Global preferences:')} ${prefsPath}`];
|
|
309
|
+
if (agentPath) {
|
|
310
|
+
configPaths.push(` ${chalk.cyan('Agent config:')} ${agentPath}`);
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
configPaths.push(` ${chalk.cyan('Agent configs:')} ~/.dexto/agents/*/`);
|
|
314
|
+
}
|
|
298
315
|
p.note([
|
|
299
316
|
`Your configuration files:`,
|
|
300
317
|
``,
|
|
301
|
-
|
|
302
|
-
` ${chalk.cyan('Agent configs:')} ~/.dexto/agents/*/`,
|
|
318
|
+
...configPaths,
|
|
303
319
|
``,
|
|
304
320
|
`Edit the appropriate file and run dexto again.`,
|
|
305
321
|
``,
|
|
306
322
|
chalk.gray('Example commands:'),
|
|
307
|
-
|
|
308
|
-
|
|
323
|
+
...(agentPath
|
|
324
|
+
? [
|
|
325
|
+
chalk.gray(` code ${agentPath} # Open in VS Code`),
|
|
326
|
+
chalk.gray(` nano ${agentPath} # Edit in terminal`),
|
|
327
|
+
]
|
|
328
|
+
: [
|
|
329
|
+
chalk.gray(` code ${prefsPath} # Open in VS Code`),
|
|
330
|
+
chalk.gray(` nano ${prefsPath} # Edit in terminal`),
|
|
331
|
+
]),
|
|
309
332
|
].join('\n'), 'Manual Configuration');
|
|
310
333
|
}
|
|
311
334
|
/**
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dexto Authentication Check
|
|
3
|
+
*
|
|
4
|
+
* Validates that users configured to use Dexto credits are properly authenticated.
|
|
5
|
+
* This prevents the confusing state where user is logged out but still has
|
|
6
|
+
* Dexto credits configured (which would fail at runtime).
|
|
7
|
+
*
|
|
8
|
+
* ## When This Check Runs
|
|
9
|
+
*
|
|
10
|
+
* - On CLI startup, after loading preferences
|
|
11
|
+
* - Before attempting to use the LLM
|
|
12
|
+
*
|
|
13
|
+
* ## Why This Exists
|
|
14
|
+
*
|
|
15
|
+
* When a user runs `dexto logout` while configured with `provider: dexto`,
|
|
16
|
+
* their preferences.yml still points to Dexto. Without this check, the CLI
|
|
17
|
+
* would attempt to use Dexto credits and fail with "Invalid API key" errors.
|
|
18
|
+
*
|
|
19
|
+
* Instead, we catch this state early and offer clear options:
|
|
20
|
+
* - Log back in to continue using Dexto credits
|
|
21
|
+
* - Run setup to configure a different provider (BYOK)
|
|
22
|
+
*
|
|
23
|
+
* @module dexto-auth-check
|
|
24
|
+
*/
|
|
25
|
+
export interface DextoAuthCheckResult {
|
|
26
|
+
shouldContinue: boolean;
|
|
27
|
+
action?: 'login' | 'setup' | 'cancel';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if user is configured to use Dexto credits but is not authenticated.
|
|
31
|
+
* This can happen if user logged out after setting up with Dexto credits.
|
|
32
|
+
*
|
|
33
|
+
* Uses getEffectiveLLMConfig() to determine the actual LLM that will be used,
|
|
34
|
+
* considering all config layers (local, preferences, bundled).
|
|
35
|
+
*
|
|
36
|
+
* @param interactive Whether to show interactive prompts
|
|
37
|
+
* @param agentId Agent to check config for (default: 'coding-agent')
|
|
38
|
+
* @returns Whether to continue startup and what action was taken
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const result = await checkDextoAuthState(true, 'coding-agent');
|
|
43
|
+
* if (!result.shouldContinue) {
|
|
44
|
+
* if (result.action === 'login') {
|
|
45
|
+
* await handleLoginCommand();
|
|
46
|
+
* } else if (result.action === 'setup') {
|
|
47
|
+
* await handleSetupCommand();
|
|
48
|
+
* }
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function checkDextoAuthState(interactive?: boolean, agentId?: string): Promise<DextoAuthCheckResult>;
|
|
53
|
+
//# sourceMappingURL=dexto-auth-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dexto-auth-check.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/dexto-auth-check.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAOH,MAAM,WAAW,oBAAoB;IACjC,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,mBAAmB,CACrC,WAAW,GAAE,OAAc,EAC3B,OAAO,GAAE,MAAuB,GACjC,OAAO,CAAC,oBAAoB,CAAC,CA8D/B"}
|