dexto 1.14.5 → 2.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/auth/billing.d.ts +0 -6
- package/dist/cli/auth/billing.d.ts.map +1 -1
- package/dist/cli/auth/billing.js +0 -23
- package/dist/cli/auth/constants.d.ts +3 -31
- package/dist/cli/auth/constants.d.ts.map +1 -1
- package/dist/cli/auth/constants.js +9 -33
- package/dist/cli/auth/index.d.ts +2 -9
- package/dist/cli/auth/index.d.ts.map +1 -1
- package/dist/cli/auth/index.js +2 -7
- package/dist/cli/auth/sign-in-runtime.d.ts +12 -0
- package/dist/cli/auth/sign-in-runtime.d.ts.map +1 -0
- package/dist/cli/auth/sign-in-runtime.js +59 -0
- package/dist/cli/cloud/app-scopes.d.ts +4 -0
- package/dist/cli/cloud/app-scopes.d.ts.map +1 -0
- package/dist/cli/cloud/app-scopes.js +19 -0
- package/dist/cli/cloud/command.d.ts +143 -0
- package/dist/cli/cloud/command.d.ts.map +1 -0
- package/dist/cli/cloud/command.js +202 -0
- package/dist/cli/cloud/commands/account.d.ts +11 -0
- package/dist/cli/cloud/commands/account.d.ts.map +1 -0
- package/dist/cli/cloud/commands/account.js +128 -0
- package/dist/cli/cloud/commands/agents.d.ts +3 -0
- package/dist/cli/cloud/commands/agents.d.ts.map +1 -0
- package/dist/cli/cloud/commands/agents.js +524 -0
- package/dist/cli/cloud/commands/api.d.ts +3 -0
- package/dist/cli/cloud/commands/api.d.ts.map +1 -0
- package/dist/cli/cloud/commands/api.js +26 -0
- package/dist/cli/cloud/commands/app-files.d.ts +29 -0
- package/dist/cli/cloud/commands/app-files.d.ts.map +1 -0
- package/dist/cli/cloud/commands/app-files.js +72 -0
- package/dist/cli/cloud/commands/automations.d.ts +3 -0
- package/dist/cli/cloud/commands/automations.d.ts.map +1 -0
- package/dist/cli/cloud/commands/automations.js +232 -0
- package/dist/cli/cloud/commands/chats.d.ts +3 -0
- package/dist/cli/cloud/commands/chats.d.ts.map +1 -0
- package/dist/cli/cloud/commands/chats.js +189 -0
- package/dist/cli/cloud/commands/data-deletions.d.ts +3 -0
- package/dist/cli/cloud/commands/data-deletions.d.ts.map +1 -0
- package/dist/cli/cloud/commands/data-deletions.js +54 -0
- package/dist/cli/cloud/commands/deploys.d.ts +10 -0
- package/dist/cli/cloud/commands/deploys.d.ts.map +1 -0
- package/dist/cli/cloud/commands/deploys.js +223 -0
- package/dist/cli/cloud/commands/drive.d.ts +12 -0
- package/dist/cli/cloud/commands/drive.d.ts.map +1 -0
- package/dist/cli/cloud/commands/drive.js +320 -0
- package/dist/cli/cloud/commands/files.d.ts +24 -0
- package/dist/cli/cloud/commands/files.d.ts.map +1 -0
- package/dist/cli/cloud/commands/files.js +282 -0
- package/dist/cli/cloud/commands/find.d.ts +3 -0
- package/dist/cli/cloud/commands/find.d.ts.map +1 -0
- package/dist/cli/cloud/commands/find.js +63 -0
- package/dist/cli/cloud/commands/models.d.ts +3 -0
- package/dist/cli/cloud/commands/models.d.ts.map +1 -0
- package/dist/cli/cloud/commands/models.js +248 -0
- package/dist/cli/cloud/commands/profile.d.ts +3 -0
- package/dist/cli/cloud/commands/profile.d.ts.map +1 -0
- package/dist/cli/cloud/commands/profile.js +119 -0
- package/dist/cli/cloud/commands/projects.d.ts +5 -0
- package/dist/cli/cloud/commands/projects.d.ts.map +1 -0
- package/dist/cli/cloud/commands/projects.js +66 -0
- package/dist/cli/cloud/commands/publish.d.ts +3 -0
- package/dist/cli/cloud/commands/publish.d.ts.map +1 -0
- package/dist/cli/cloud/commands/publish.js +138 -0
- package/dist/cli/cloud/commands/sandboxes.d.ts +3 -0
- package/dist/cli/cloud/commands/sandboxes.d.ts.map +1 -0
- package/dist/cli/cloud/commands/sandboxes.js +265 -0
- package/dist/cli/cloud/commands/secrets.d.ts +3 -0
- package/dist/cli/cloud/commands/secrets.d.ts.map +1 -0
- package/dist/cli/cloud/commands/secrets.js +110 -0
- package/dist/cli/cloud/commands/skills.d.ts +3 -0
- package/dist/cli/cloud/commands/skills.d.ts.map +1 -0
- package/dist/cli/cloud/commands/skills.js +202 -0
- package/dist/cli/cloud/commands/web.d.ts +3 -0
- package/dist/cli/cloud/commands/web.d.ts.map +1 -0
- package/dist/cli/cloud/commands/web.js +53 -0
- package/dist/cli/cloud/commands/workspace-apps.d.ts +58 -0
- package/dist/cli/cloud/commands/workspace-apps.d.ts.map +1 -0
- package/dist/cli/cloud/commands/workspace-apps.js +656 -0
- package/dist/cli/cloud/commands/workspace.d.ts +36 -0
- package/dist/cli/cloud/commands/workspace.d.ts.map +1 -0
- package/dist/cli/cloud/commands/workspace.js +279 -0
- package/dist/cli/cloud/connection.d.ts +33 -0
- package/dist/cli/cloud/connection.d.ts.map +1 -0
- package/dist/cli/cloud/connection.js +38 -0
- package/dist/cli/cloud/events.d.ts +63 -0
- package/dist/cli/cloud/events.d.ts.map +1 -0
- package/dist/cli/cloud/events.js +72 -0
- package/dist/cli/cloud/host.d.ts +9 -0
- package/dist/cli/cloud/host.d.ts.map +1 -0
- package/dist/cli/cloud/host.js +105 -0
- package/dist/cli/cloud/local-chats.d.ts +73 -0
- package/dist/cli/cloud/local-chats.d.ts.map +1 -0
- package/dist/cli/cloud/local-chats.js +441 -0
- package/dist/cli/cloud/output.d.ts +34 -0
- package/dist/cli/cloud/output.d.ts.map +1 -0
- package/dist/cli/cloud/output.js +76 -0
- package/dist/cli/cloud/run.d.ts +26 -0
- package/dist/cli/cloud/run.d.ts.map +1 -0
- package/dist/cli/cloud/run.js +444 -0
- package/dist/cli/cloud/runtime.d.ts +33 -0
- package/dist/cli/cloud/runtime.d.ts.map +1 -0
- package/dist/cli/cloud/runtime.js +86 -0
- package/dist/cli/cloud/tar.d.ts +9 -0
- package/dist/cli/cloud/tar.d.ts.map +1 -0
- package/dist/cli/cloud/tar.js +69 -0
- package/dist/cli/cloud/transfer.d.ts +13 -0
- package/dist/cli/cloud/transfer.d.ts.map +1 -0
- package/dist/cli/cloud/transfer.js +35 -0
- package/dist/cli/cloud/v1.d.ts +19 -0
- package/dist/cli/cloud/v1.d.ts.map +1 -0
- package/dist/cli/cloud/v1.js +65 -0
- package/dist/cli/cloud/zip.d.ts +8 -0
- package/dist/cli/cloud/zip.d.ts.map +1 -0
- package/dist/cli/cloud/zip.js +66 -0
- package/dist/cli/commands/auth/sign-in-commands.d.ts +62 -0
- package/dist/cli/commands/auth/sign-in-commands.d.ts.map +1 -0
- package/dist/cli/commands/auth/sign-in-commands.js +247 -0
- package/dist/cli/commands/auth/sign-in-context.d.ts +16 -0
- package/dist/cli/commands/auth/sign-in-context.d.ts.map +1 -0
- package/dist/cli/commands/auth/sign-in-context.js +68 -0
- package/dist/cli/commands/cloud/register.d.ts +5 -0
- package/dist/cli/commands/cloud/register.d.ts.map +1 -1
- package/dist/cli/commands/cloud/register.js +42 -24
- package/dist/cli/commands/create-app.js +5 -6
- package/dist/cli/commands/create-image.d.ts.map +1 -1
- package/dist/cli/commands/create-image.js +9 -10
- package/dist/cli/commands/index.d.ts +0 -2
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +0 -2
- package/dist/cli/commands/init.d.ts +0 -2
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +5 -26
- package/dist/cli/commands/run/headless.js +2 -2
- package/dist/cli/commands/run/output.d.ts +29 -10
- package/dist/cli/commands/run/output.d.ts.map +1 -1
- package/dist/cli/commands/run/output.js +44 -22
- package/dist/cli/commands/run/register.d.ts.map +1 -1
- package/dist/cli/commands/run/register.js +21 -9
- package/dist/cli/commands/session/register.d.ts.map +1 -1
- package/dist/cli/commands/session/register.js +51 -21
- package/dist/cli/commands/session-commands.js +1 -1
- package/dist/cli/commands/setup.js +17 -14
- package/dist/cli/help-json.d.ts +22 -0
- package/dist/cli/help-json.d.ts.map +1 -0
- package/dist/cli/help-json.js +20 -0
- package/dist/cli/modes/cli.d.ts.map +1 -1
- package/dist/cli/modes/cli.js +42 -9
- package/dist/cli/modes/server.js +8 -8
- package/dist/cli/modes/web.js +3 -3
- package/dist/cli/utils/dexto-auth-check.d.ts +1 -1
- package/dist/cli/utils/dexto-auth-check.d.ts.map +1 -1
- package/dist/cli/utils/dexto-auth-check.js +4 -5
- package/dist/cli/utils/dexto-setup.d.ts +4 -5
- package/dist/cli/utils/dexto-setup.d.ts.map +1 -1
- package/dist/cli/utils/dexto-setup.js +17 -14
- package/dist/cli/utils/provider-setup.js +1 -1
- package/dist/cli/utils/scaffolding-utils.d.ts +9 -3
- package/dist/cli/utils/scaffolding-utils.d.ts.map +1 -1
- package/dist/cli/utils/scaffolding-utils.js +48 -40
- package/dist/cli/utils/version-check.d.ts.map +1 -1
- package/dist/cli/utils/version-check.js +2 -1
- package/dist/index-main.js +33 -65
- package/dist/webui/assets/index-D9xiOs62.js +1649 -0
- package/dist/webui/index.html +1 -1
- package/package.json +15 -14
- package/dist/cli/auth/api-client.d.ts +0 -125
- package/dist/cli/auth/api-client.d.ts.map +0 -1
- package/dist/cli/auth/api-client.js +0 -585
- package/dist/cli/auth/device.d.ts +0 -14
- package/dist/cli/auth/device.d.ts.map +0 -1
- package/dist/cli/auth/device.js +0 -84
- package/dist/cli/auth/dexto-api-key.d.ts +0 -34
- package/dist/cli/auth/dexto-api-key.d.ts.map +0 -1
- package/dist/cli/auth/dexto-api-key.js +0 -160
- package/dist/cli/auth/login-persistence.d.ts +0 -15
- package/dist/cli/auth/login-persistence.d.ts.map +0 -1
- package/dist/cli/auth/login-persistence.js +0 -72
- package/dist/cli/auth/oauth.d.ts +0 -39
- package/dist/cli/auth/oauth.d.ts.map +0 -1
- package/dist/cli/auth/oauth.js +0 -434
- package/dist/cli/auth/service.d.ts +0 -24
- package/dist/cli/auth/service.d.ts.map +0 -1
- package/dist/cli/auth/service.js +0 -161
- package/dist/cli/auth/types.d.ts +0 -11
- package/dist/cli/auth/types.d.ts.map +0 -1
- package/dist/cli/auth/types.js +0 -1
- package/dist/cli/cloud-chat.d.ts +0 -18
- package/dist/cli/cloud-chat.d.ts.map +0 -1
- package/dist/cli/cloud-chat.js +0 -734
- package/dist/cli/commands/auth/index.d.ts +0 -4
- package/dist/cli/commands/auth/index.d.ts.map +0 -1
- package/dist/cli/commands/auth/index.js +0 -4
- package/dist/cli/commands/auth/login.d.ts +0 -12
- package/dist/cli/commands/auth/login.d.ts.map +0 -1
- package/dist/cli/commands/auth/login.js +0 -153
- package/dist/cli/commands/auth/logout.d.ts +0 -5
- package/dist/cli/commands/auth/logout.d.ts.map +0 -1
- package/dist/cli/commands/auth/logout.js +0 -81
- package/dist/cli/commands/auth/register.d.ts +0 -3
- package/dist/cli/commands/auth/register.d.ts.map +0 -1
- package/dist/cli/commands/auth/register.js +0 -96
- package/dist/cli/commands/auth/status.d.ts +0 -2
- package/dist/cli/commands/auth/status.d.ts.map +0 -1
- package/dist/cli/commands/auth/status.js +0 -22
- package/dist/cli/commands/billing/index.d.ts +0 -2
- package/dist/cli/commands/billing/index.d.ts.map +0 -1
- package/dist/cli/commands/billing/index.js +0 -2
- package/dist/cli/commands/billing/register.d.ts +0 -3
- package/dist/cli/commands/billing/register.d.ts.map +0 -1
- package/dist/cli/commands/billing/register.js +0 -20
- package/dist/cli/commands/billing/status.d.ts +0 -8
- package/dist/cli/commands/billing/status.d.ts.map +0 -1
- package/dist/cli/commands/billing/status.js +0 -71
- package/dist/cli/commands/cloud/discovery.d.ts +0 -17
- package/dist/cli/commands/cloud/discovery.d.ts.map +0 -1
- package/dist/cli/commands/cloud/discovery.js +0 -88
- package/dist/cli/commands/deploy/client.d.ts +0 -113
- package/dist/cli/commands/deploy/client.d.ts.map +0 -1
- package/dist/cli/commands/deploy/client.js +0 -519
- package/dist/cli/commands/deploy/config.d.ts +0 -37
- package/dist/cli/commands/deploy/config.d.ts.map +0 -1
- package/dist/cli/commands/deploy/config.js +0 -144
- package/dist/cli/commands/deploy/entry-agent.d.ts +0 -3
- package/dist/cli/commands/deploy/entry-agent.d.ts.map +0 -1
- package/dist/cli/commands/deploy/entry-agent.js +0 -70
- package/dist/cli/commands/deploy/index.d.ts +0 -12
- package/dist/cli/commands/deploy/index.d.ts.map +0 -1
- package/dist/cli/commands/deploy/index.js +0 -370
- package/dist/cli/commands/deploy/links.d.ts +0 -3
- package/dist/cli/commands/deploy/links.d.ts.map +0 -1
- package/dist/cli/commands/deploy/links.js +0 -53
- package/dist/cli/commands/deploy/register.d.ts +0 -6
- package/dist/cli/commands/deploy/register.d.ts.map +0 -1
- package/dist/cli/commands/deploy/register.js +0 -128
- package/dist/cli/commands/deploy/snapshot.d.ts +0 -12
- package/dist/cli/commands/deploy/snapshot.d.ts.map +0 -1
- package/dist/cli/commands/deploy/snapshot.js +0 -76
- package/dist/cli/commands/deploy/state.d.ts +0 -13
- package/dist/cli/commands/deploy/state.d.ts.map +0 -1
- package/dist/cli/commands/deploy/state.js +0 -122
- package/dist/cli/commands/span/register.d.ts +0 -6
- package/dist/cli/commands/span/register.d.ts.map +0 -1
- package/dist/cli/commands/span/register.js +0 -25
- package/dist/cli/commands/trace/client.d.ts +0 -98
- package/dist/cli/commands/trace/client.d.ts.map +0 -1
- package/dist/cli/commands/trace/client.js +0 -150
- package/dist/cli/commands/trace/format.d.ts +0 -5
- package/dist/cli/commands/trace/format.d.ts.map +0 -1
- package/dist/cli/commands/trace/format.js +0 -58
- package/dist/cli/commands/trace/index.d.ts +0 -21
- package/dist/cli/commands/trace/index.d.ts.map +0 -1
- package/dist/cli/commands/trace/index.js +0 -49
- package/dist/cli/commands/trace/register.d.ts +0 -6
- package/dist/cli/commands/trace/register.d.ts.map +0 -1
- package/dist/cli/commands/trace/register.js +0 -71
- package/dist/webui/assets/index-DEfRFmFT.js +0 -1667
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import type { BillingCheckoutSessionResponse } from './api-client.js';
|
|
2
1
|
export declare function buildDextoBillingUrl(options: {
|
|
3
2
|
creditsUsd?: number | undefined;
|
|
4
3
|
baseUrl?: string | undefined;
|
|
5
4
|
}): string;
|
|
6
|
-
export declare function getBillingBalanceForCurrentLogin(): Promise<number | null>;
|
|
7
|
-
export declare function createBillingCheckoutForCurrentLogin(options: {
|
|
8
|
-
creditsUsd: number;
|
|
9
|
-
returnUrl?: string | undefined;
|
|
10
|
-
}): Promise<BillingCheckoutSessionResponse>;
|
|
11
5
|
export declare function openDextoBillingPage(options: {
|
|
12
6
|
url?: string | undefined;
|
|
13
7
|
}): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/billing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"billing.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/billing.ts"],"names":[],"mappings":"AAGA,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC1C,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,GAAG,MAAM,CAQT;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/F"}
|
package/dist/cli/auth/billing.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import { getDextoApiClient } from './api-client.js';
|
|
2
1
|
import { openBrowserUrl } from './browser-launch.js';
|
|
3
2
|
import { DEXTO_CREDITS_URL } from './constants.js';
|
|
4
|
-
import { getAuthTokenQuietly } from './service.js';
|
|
5
|
-
function notLoggedInError() {
|
|
6
|
-
return new Error('Not logged in to Dexto');
|
|
7
|
-
}
|
|
8
3
|
export function buildDextoBillingUrl(options) {
|
|
9
4
|
const url = new URL(options.baseUrl ?? DEXTO_CREDITS_URL);
|
|
10
5
|
if (typeof options.creditsUsd === 'number' && Number.isFinite(options.creditsUsd)) {
|
|
@@ -12,24 +7,6 @@ export function buildDextoBillingUrl(options) {
|
|
|
12
7
|
}
|
|
13
8
|
return url.toString();
|
|
14
9
|
}
|
|
15
|
-
export async function getBillingBalanceForCurrentLogin() {
|
|
16
|
-
const authToken = await getAuthTokenQuietly();
|
|
17
|
-
if (!authToken) {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
const response = await getDextoApiClient().getBillingBalance(authToken, {});
|
|
21
|
-
return response.creditsUsd;
|
|
22
|
-
}
|
|
23
|
-
export async function createBillingCheckoutForCurrentLogin(options) {
|
|
24
|
-
const authToken = await getAuthTokenQuietly();
|
|
25
|
-
if (!authToken) {
|
|
26
|
-
throw notLoggedInError();
|
|
27
|
-
}
|
|
28
|
-
return getDextoApiClient().createBillingCheckoutSession(authToken, {
|
|
29
|
-
...options,
|
|
30
|
-
returnUrl: options.returnUrl ?? DEXTO_CREDITS_URL,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
10
|
export async function openDextoBillingPage(options) {
|
|
34
11
|
await openBrowserUrl(options.url ?? DEXTO_CREDITS_URL);
|
|
35
12
|
}
|
|
@@ -1,35 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dexto's Supabase configuration for CLI authentication.
|
|
3
|
-
*
|
|
4
|
-
* SECURITY NOTE:
|
|
5
|
-
* The Supabase anon key is safe to hardcode in distributed code because:
|
|
6
|
-
* 1. It's designed for client-side use (web browsers, mobile apps, CLIs)
|
|
7
|
-
* 2. It only grants anonymous access - real security is enforced by Row Level Security (RLS)
|
|
8
|
-
* 3. This is standard practice (Vercel CLI, Supabase CLI, Firebase CLI all do the same)
|
|
9
|
-
*
|
|
10
|
-
* The service role key (which has admin access) is NEVER in this codebase.
|
|
11
|
-
*
|
|
12
|
-
* Environment variable overrides (for local development):
|
|
13
|
-
* - SUPABASE_URL: Override Supabase URL (e.g., http://localhost:54321)
|
|
14
|
-
* - SUPABASE_ANON_KEY: Override anon key (from `supabase start` output)
|
|
15
|
-
* - DEXTO_API_URL: Override Dexto gateway URL for data-plane calls (e.g., http://localhost:3001)
|
|
16
|
-
* - DEXTO_PLATFORM_URL: Override Dexto app URL for auth/key/account control-plane calls (e.g., http://localhost:3002)
|
|
17
|
-
* - DEXTO_PUBLIC_API_URL: Override versioned public API URL (e.g., http://localhost:3002)
|
|
18
|
-
*/
|
|
19
|
-
export declare const SUPABASE_URL: string;
|
|
20
|
-
export declare const SUPABASE_ANON_KEY: string;
|
|
21
|
-
/**
|
|
22
|
-
* Dexto gateway URL for retained data-plane endpoints.
|
|
23
|
-
*/
|
|
24
|
-
export declare const DEXTO_API_URL: string;
|
|
25
|
-
/**
|
|
26
|
-
* Dexto app URL for auth/key/account control-plane endpoints.
|
|
27
|
-
*/
|
|
28
|
-
export declare const DEFAULT_DEXTO_PLATFORM_URL = "https://app.dexto.ai";
|
|
1
|
+
/** The Dexto app a new sign-in goes to. */
|
|
29
2
|
export declare const DEXTO_PLATFORM_URL: string;
|
|
3
|
+
/** The versioned public API (`/v1`). */
|
|
30
4
|
export declare const DEXTO_PUBLIC_API_URL: string;
|
|
31
|
-
/**
|
|
32
|
-
* Dexto Nova credits purchase URL
|
|
33
|
-
*/
|
|
5
|
+
/** Where to buy Dexto credits. */
|
|
34
6
|
export declare const DEXTO_CREDITS_URL: string;
|
|
35
7
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/constants.ts"],"names":[],"mappings":"AAOA,2CAA2C;AAC3C,eAAO,MAAM,kBAAkB,QAA2D,CAAC;AAE3F,wCAAwC;AACxC,eAAO,MAAM,oBAAoB,QAA6D,CAAC;AAE/F,kCAAkC;AAClC,eAAO,MAAM,iBAAiB,QACwD,CAAC"}
|
|
@@ -1,36 +1,12 @@
|
|
|
1
1
|
// packages/cli/src/cli/auth/constants.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*
|
|
11
|
-
* The service role key (which has admin access) is NEVER in this codebase.
|
|
12
|
-
*
|
|
13
|
-
* Environment variable overrides (for local development):
|
|
14
|
-
* - SUPABASE_URL: Override Supabase URL (e.g., http://localhost:54321)
|
|
15
|
-
* - SUPABASE_ANON_KEY: Override anon key (from `supabase start` output)
|
|
16
|
-
* - DEXTO_API_URL: Override Dexto gateway URL for data-plane calls (e.g., http://localhost:3001)
|
|
17
|
-
* - DEXTO_PLATFORM_URL: Override Dexto app URL for auth/key/account control-plane calls (e.g., http://localhost:3002)
|
|
18
|
-
* - DEXTO_PUBLIC_API_URL: Override versioned public API URL (e.g., http://localhost:3002)
|
|
19
|
-
*/
|
|
20
|
-
export const SUPABASE_URL = process.env.SUPABASE_URL || 'https://gdfbxznhnnsamvsrtwjq.supabase.co';
|
|
21
|
-
export const SUPABASE_ANON_KEY = process.env.SUPABASE_ANON_KEY ||
|
|
22
|
-
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImdkZmJ4em5obm5zYW12c3J0d2pxIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjQwNjkzNjksImV4cCI6MjA3OTY0NTM2OX0.j2NWOJDOy8gTT84XeomalkGSPpLdPvTCBnQMrTgdlI4';
|
|
23
|
-
/**
|
|
24
|
-
* Dexto gateway URL for retained data-plane endpoints.
|
|
25
|
-
*/
|
|
26
|
-
export const DEXTO_API_URL = process.env.DEXTO_API_URL || 'https://app.dexto.ai';
|
|
27
|
-
/**
|
|
28
|
-
* Dexto app URL for auth/key/account control-plane endpoints.
|
|
29
|
-
*/
|
|
30
|
-
export const DEFAULT_DEXTO_PLATFORM_URL = 'https://app.dexto.ai';
|
|
31
|
-
export const DEXTO_PLATFORM_URL = process.env.DEXTO_PLATFORM_URL || DEFAULT_DEXTO_PLATFORM_URL;
|
|
2
|
+
//
|
|
3
|
+
// Where the CLI reaches Dexto. Environment overrides, for previews and local development:
|
|
4
|
+
// - DEXTO_PLATFORM_URL: the Dexto app, home of its OAuth server and MCP (e.g. http://localhost:3002)
|
|
5
|
+
// - DEXTO_PUBLIC_API_URL: the versioned public API (e.g. http://localhost:3002)
|
|
6
|
+
// - DEXTO_CREDITS_URL: the page to buy credits on
|
|
7
|
+
/** The Dexto app a new sign-in goes to. */
|
|
8
|
+
export const DEXTO_PLATFORM_URL = process.env.DEXTO_PLATFORM_URL || 'https://app.dexto.ai';
|
|
9
|
+
/** The versioned public API (`/v1`). */
|
|
32
10
|
export const DEXTO_PUBLIC_API_URL = process.env.DEXTO_PUBLIC_API_URL || 'https://api.dexto.ai';
|
|
33
|
-
/**
|
|
34
|
-
* Dexto Nova credits purchase URL
|
|
35
|
-
*/
|
|
11
|
+
/** Where to buy Dexto credits. */
|
|
36
12
|
export const DEXTO_CREDITS_URL = process.env.DEXTO_CREDITS_URL || 'https://app.dexto.ai/dashboard/settings/billing';
|
package/dist/cli/auth/index.d.ts
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export { type DeviceApiKeyLoginResult } from './types.js';
|
|
4
|
-
export { type DeviceLoginPrompt, performDeviceCodeLogin } from './device.js';
|
|
5
|
-
export { type PersistOAuthLoginOptions, type PersistedLoginResult, persistDeviceApiKeyLoginResult, persistOAuthLoginResult, } from './login-persistence.js';
|
|
6
|
-
export { type UsageSummaryResponse, DextoApiClient, getDextoApiClient } from './api-client.js';
|
|
7
|
-
export { SUPABASE_URL, SUPABASE_ANON_KEY, DEXTO_API_URL, DEXTO_PLATFORM_URL, DEXTO_PUBLIC_API_URL, } from './constants.js';
|
|
8
|
-
export { buildDextoBillingUrl, getBillingBalanceForCurrentLogin, createBillingCheckoutForCurrentLogin, openDextoBillingPage, } from './billing.js';
|
|
9
|
-
export { type DextoApiKeyProvisionStatus, type DextoApiKeyProvisionStatusLevel, type EnsureDextoApiKeyOptions, ensureDextoApiKeyForAuthToken, saveDextoApiKeyToEnv, removeDextoApiKeyFromEnv, } from './dexto-api-key.js';
|
|
1
|
+
export { DEXTO_PLATFORM_URL, DEXTO_PUBLIC_API_URL } from './constants.js';
|
|
2
|
+
export { buildDextoBillingUrl, openDextoBillingPage } from './billing.js';
|
|
10
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/index.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/cli/auth/index.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
// packages/cli/src/cli/auth/index.ts
|
|
2
2
|
// Public exports for auth module
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export { persistDeviceApiKeyLoginResult, persistOAuthLoginResult, } from './login-persistence.js';
|
|
6
|
-
export { DextoApiClient, getDextoApiClient } from './api-client.js';
|
|
7
|
-
export { SUPABASE_URL, SUPABASE_ANON_KEY, DEXTO_API_URL, DEXTO_PLATFORM_URL, DEXTO_PUBLIC_API_URL, } from './constants.js';
|
|
8
|
-
export { buildDextoBillingUrl, getBillingBalanceForCurrentLogin, createBillingCheckoutForCurrentLogin, openDextoBillingPage, } from './billing.js';
|
|
9
|
-
export { ensureDextoApiKeyForAuthToken, saveDextoApiKeyToEnv, removeDextoApiKeyFromEnv, } from './dexto-api-key.js';
|
|
3
|
+
export { DEXTO_PLATFORM_URL, DEXTO_PUBLIC_API_URL } from './constants.js';
|
|
4
|
+
export { buildDextoBillingUrl, openDextoBillingPage } from './billing.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { dextoSignIn } from '@dexto/agent-management';
|
|
2
|
+
type RedirectListener = dextoSignIn.RedirectListener;
|
|
3
|
+
type SignInRuntime = dextoSignIn.SignInRuntime;
|
|
4
|
+
/**
|
|
5
|
+
* Listens on 127.0.0.1 at any free port for the browser's redirect to `/callback` (RFC 8252), and
|
|
6
|
+
* resolves with its query on the first one.
|
|
7
|
+
*/
|
|
8
|
+
export declare function listenForRedirect(): Promise<RedirectListener>;
|
|
9
|
+
/** Signing in from this process: notes go to stderr so stdout stays for results. */
|
|
10
|
+
export declare function nodeSignInRuntime(signal: AbortSignal): SignInRuntime;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=sign-in-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign-in-runtime.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/sign-in-runtime.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,KAAK,gBAAgB,GAAG,WAAW,CAAC,gBAAgB,CAAC;AACrD,KAAK,aAAa,GAAG,WAAW,CAAC,aAAa,CAAC;AAM/C;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CA6BnE;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,aAAa,CAepE"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// The Node side of signing in: a loopback redirect listener, the browser and timers.
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
|
+
import { setTimeout as sleep } from 'node:timers/promises';
|
|
4
|
+
import { openBrowserUrl } from './browser-launch.js';
|
|
5
|
+
const DONE_PAGE = `<!doctype html><meta charset="utf-8"><title>Dexto</title>
|
|
6
|
+
<body style="font-family:system-ui;margin:4rem auto;max-width:28rem">
|
|
7
|
+
<h1>Signed in</h1><p>You can close this tab and return to your terminal.</p></body>`;
|
|
8
|
+
/**
|
|
9
|
+
* Listens on 127.0.0.1 at any free port for the browser's redirect to `/callback` (RFC 8252), and
|
|
10
|
+
* resolves with its query on the first one.
|
|
11
|
+
*/
|
|
12
|
+
export async function listenForRedirect() {
|
|
13
|
+
let deliver = () => undefined;
|
|
14
|
+
const result = new Promise((resolve) => {
|
|
15
|
+
deliver = resolve;
|
|
16
|
+
});
|
|
17
|
+
const server = createServer((request, response) => {
|
|
18
|
+
const url = new URL(request.url ?? '/', 'http://127.0.0.1');
|
|
19
|
+
if (request.method !== 'GET' || url.pathname !== '/callback') {
|
|
20
|
+
response.writeHead(404).end();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
response.writeHead(200, { 'content-type': 'text/html; charset=utf-8' }).end(DONE_PAGE);
|
|
24
|
+
deliver(url.searchParams);
|
|
25
|
+
});
|
|
26
|
+
await new Promise((resolve, reject) => {
|
|
27
|
+
server.once('error', reject);
|
|
28
|
+
server.listen(0, '127.0.0.1', () => resolve());
|
|
29
|
+
});
|
|
30
|
+
const address = server.address();
|
|
31
|
+
if (address === null || typeof address === 'string')
|
|
32
|
+
throw new Error('The sign-in listener has no port.');
|
|
33
|
+
return {
|
|
34
|
+
redirectUri: `http://127.0.0.1:${address.port}/callback`,
|
|
35
|
+
result,
|
|
36
|
+
close: () => {
|
|
37
|
+
server.closeAllConnections();
|
|
38
|
+
server.close();
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Signing in from this process: notes go to stderr so stdout stays for results. */
|
|
43
|
+
export function nodeSignInRuntime(signal) {
|
|
44
|
+
return {
|
|
45
|
+
fetch: globalThis.fetch,
|
|
46
|
+
signal,
|
|
47
|
+
note: (text) => process.stderr.write(`${text}\n`),
|
|
48
|
+
openBrowser: async (url) => {
|
|
49
|
+
try {
|
|
50
|
+
await openBrowserUrl(url);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// The URL was already printed; the person opens it by hand.
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
listenForRedirect,
|
|
57
|
+
sleep: (ms) => sleep(ms, undefined, { signal }),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CloudRuntime } from './runtime.js';
|
|
2
|
+
/** Each app's operations by tool or action name, with their scopes; empty from an older server. */
|
|
3
|
+
export declare function readAppScopes(runtime: CloudRuntime, appUrl: string): Promise<ReadonlyMap<string, Readonly<Record<string, readonly string[]>>>>;
|
|
4
|
+
//# sourceMappingURL=app-scopes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-scopes.d.ts","sourceRoot":"","sources":["../../../src/cli/cloud/app-scopes.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAOjD,mGAAmG;AACnG,wBAAsB,aAAa,CAC/B,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAS3E"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Each workspace app's operations and the scopes each takes, from the MCP's published metadata,
|
|
2
|
+
// so a command can sign in for an operation the sign-in can't see yet.
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
const ProtectedResourceSchema = z.object({
|
|
5
|
+
/** Every scope each app's operations take; an older server publishes none. */
|
|
6
|
+
dexto_app_scopes: z.record(z.string(), z.record(z.string(), z.array(z.string()))).optional(),
|
|
7
|
+
});
|
|
8
|
+
/** Each app's operations by tool or action name, with their scopes; empty from an older server. */
|
|
9
|
+
export async function readAppScopes(runtime, appUrl) {
|
|
10
|
+
const url = `${appUrl.replace(/\/+$/u, '')}/.well-known/oauth-protected-resource/mcp`;
|
|
11
|
+
const response = await runtime.fetch(url, {
|
|
12
|
+
headers: { accept: 'application/json' },
|
|
13
|
+
signal: runtime.signal,
|
|
14
|
+
});
|
|
15
|
+
if (!response.ok)
|
|
16
|
+
throw new Error(`${url} answered HTTP ${response.status}.`);
|
|
17
|
+
const metadata = ProtectedResourceSchema.parse(await response.json());
|
|
18
|
+
return new Map(Object.entries(metadata.dexto_app_scopes ?? {}));
|
|
19
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type { CloudClient } from '@dexto/cloud-client';
|
|
2
|
+
import type { Connection, ConnectionOverrides } from './connection.js';
|
|
3
|
+
import type { Output } from './output.js';
|
|
4
|
+
import type { CloudRuntime } from './runtime.js';
|
|
5
|
+
export interface OptionSpec {
|
|
6
|
+
readonly description: string;
|
|
7
|
+
readonly multiple?: true;
|
|
8
|
+
readonly short?: string;
|
|
9
|
+
readonly type: 'boolean' | 'string';
|
|
10
|
+
/** The value's name in help, such as ID; string options only. */
|
|
11
|
+
readonly valueName?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface Command {
|
|
14
|
+
/** Such as `<agent_id> [message...]`; `<x>` is required, `[x]` optional. */
|
|
15
|
+
readonly arguments?: string;
|
|
16
|
+
readonly options?: Readonly<Record<string, OptionSpec>>;
|
|
17
|
+
/** The words that select it, such as ["agents", "sessions", "list"]. */
|
|
18
|
+
readonly path: readonly string[];
|
|
19
|
+
readonly summary: string;
|
|
20
|
+
run(context: CommandContext, input: CommandInput): Promise<number | void>;
|
|
21
|
+
}
|
|
22
|
+
export interface CommandInput {
|
|
23
|
+
readonly positionals: readonly string[];
|
|
24
|
+
readonly values: Readonly<Record<string, string | boolean | (string | boolean)[] | undefined>>;
|
|
25
|
+
}
|
|
26
|
+
export interface CommandContext {
|
|
27
|
+
/** The /v1 client for the resolved credential; fails with how to sign in when there is none. */
|
|
28
|
+
client(): Promise<CloudClient>;
|
|
29
|
+
connection(): Promise<Connection>;
|
|
30
|
+
/** The words the command was run with, its connection options included and any key left out. */
|
|
31
|
+
readonly invocation: readonly string[];
|
|
32
|
+
readonly output: Output;
|
|
33
|
+
readonly overrides: ConnectionOverrides;
|
|
34
|
+
readonly runtime: CloudRuntime;
|
|
35
|
+
}
|
|
36
|
+
/** A mistake in how the command was called: printed with the command's usage. */
|
|
37
|
+
export declare class UsageError extends Error {
|
|
38
|
+
constructor(message: string);
|
|
39
|
+
}
|
|
40
|
+
/** What kind of thing went wrong; each kind has an exit code an agent can branch on. */
|
|
41
|
+
export type FailureKind = 'failed' | 'invalid_input' | 'needs_confirmation' | 'needs_permission' | 'needs_sign_in' | 'not_found' | 'waiting_on_person';
|
|
42
|
+
export declare const EXIT_CODES: {
|
|
43
|
+
readonly failed: 1;
|
|
44
|
+
readonly invalid_input: 2;
|
|
45
|
+
readonly needs_confirmation: 4;
|
|
46
|
+
readonly needs_permission: 3;
|
|
47
|
+
readonly needs_sign_in: 3;
|
|
48
|
+
readonly not_found: 5;
|
|
49
|
+
readonly waiting_on_person: 6;
|
|
50
|
+
readonly usage: 2;
|
|
51
|
+
};
|
|
52
|
+
/** What each exit code means; frozen in 2.0 and shown in help. */
|
|
53
|
+
export declare const EXIT_CODE_MEANINGS: {
|
|
54
|
+
readonly '0': "done";
|
|
55
|
+
readonly '1': "failed";
|
|
56
|
+
readonly '2': "usage or invalid input";
|
|
57
|
+
readonly '3': "needs sign-in or permission";
|
|
58
|
+
readonly '4': "needs confirmation: pass --yes once your person has agreed";
|
|
59
|
+
readonly '5': "not found";
|
|
60
|
+
readonly '6': "waiting on a person, such as an approval";
|
|
61
|
+
};
|
|
62
|
+
/** A failure that says what kind it is and, where there is one, the command that fixes it. */
|
|
63
|
+
export declare class CommandFailure extends Error {
|
|
64
|
+
readonly fix: string | null;
|
|
65
|
+
readonly kind: FailureKind;
|
|
66
|
+
constructor(kind: FailureKind, message: string, fix: string | null);
|
|
67
|
+
}
|
|
68
|
+
/** A permission the sign-in lacks: signing in again for `scope` (one, or several comma-separated) fixes it. */
|
|
69
|
+
export declare class MissingScopeFailure extends CommandFailure {
|
|
70
|
+
readonly scope: string;
|
|
71
|
+
constructor(context: SignInContext, scope: string, message: string);
|
|
72
|
+
}
|
|
73
|
+
export declare function stringOption(input: CommandInput, name: string): string | undefined;
|
|
74
|
+
export declare function requiredOption(input: CommandInput, name: string): string;
|
|
75
|
+
export declare function listOption(input: CommandInput, name: string): string[];
|
|
76
|
+
export declare function flag(input: CommandInput, name: string): boolean;
|
|
77
|
+
export declare function integerOption(input: CommandInput, name: string): number | undefined;
|
|
78
|
+
export declare function argument(input: CommandInput, index: number, name: string): string;
|
|
79
|
+
/** `--limit` and `--after`, which every list takes. */
|
|
80
|
+
export declare const PAGE_OPTIONS: {
|
|
81
|
+
readonly after: {
|
|
82
|
+
readonly description: "Start after this cursor, from the previous page.";
|
|
83
|
+
readonly type: "string";
|
|
84
|
+
readonly valueName: "CURSOR";
|
|
85
|
+
};
|
|
86
|
+
readonly limit: {
|
|
87
|
+
readonly description: "How many to return.";
|
|
88
|
+
readonly type: "string";
|
|
89
|
+
readonly valueName: "N";
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
export declare function pageQuery(input: CommandInput): {
|
|
93
|
+
after?: string;
|
|
94
|
+
limit?: number;
|
|
95
|
+
};
|
|
96
|
+
/** `--data <json>` and `--file <path|->`, for request bodies too rich for flags. */
|
|
97
|
+
export declare const BODY_OPTIONS: {
|
|
98
|
+
readonly data: {
|
|
99
|
+
readonly description: "The request body as JSON.";
|
|
100
|
+
readonly type: "string";
|
|
101
|
+
readonly valueName: "JSON";
|
|
102
|
+
};
|
|
103
|
+
readonly file: {
|
|
104
|
+
readonly description: "Read the request body from a JSON file, or - for stdin.";
|
|
105
|
+
readonly type: "string";
|
|
106
|
+
readonly valueName: "PATH";
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
/** The JSON body from --data or --file; null when neither was given. */
|
|
110
|
+
export declare function readJsonBody(context: CommandContext, input: CommandInput): Promise<unknown>;
|
|
111
|
+
export declare function isJsonObject(value: unknown): value is Record<string, unknown>;
|
|
112
|
+
/** A value the person types, hidden when secret, or piped on stdin. */
|
|
113
|
+
export declare function readValue(context: CommandContext, question: string, secret: boolean): Promise<string>;
|
|
114
|
+
/** Asks yes or no at a terminal; without one, only `--yes` agrees. */
|
|
115
|
+
export declare function confirm(context: CommandContext, question: string): Promise<boolean>;
|
|
116
|
+
export declare const YES_OPTION: {
|
|
117
|
+
readonly yes: {
|
|
118
|
+
readonly description: "Go ahead without being asked. Pass it only once your person has agreed.";
|
|
119
|
+
readonly type: "boolean";
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Goes ahead with something that asks first: at once with `--yes`, after a yes at a terminal, and
|
|
124
|
+
* otherwise not at all, failing with the command that goes ahead.
|
|
125
|
+
*/
|
|
126
|
+
export declare function requireConsent(context: CommandContext, yes: boolean, what: string): Promise<void>;
|
|
127
|
+
/** The command as it was run plus more words, quoted to paste into a shell. */
|
|
128
|
+
export declare function rerunWith(context: CommandContext, ...extra: string[]): string;
|
|
129
|
+
/**
|
|
130
|
+
* Whether a sign-in here should use a device code: no one is at this terminal, or it is an SSH
|
|
131
|
+
* session, whose loopback redirect a browser on the person's own device can't reach.
|
|
132
|
+
*/
|
|
133
|
+
export declare function signsInWithDevice(runtime: CloudRuntime): boolean;
|
|
134
|
+
/** What saying how to sign in again needs: the process, and the profile `--profile` chose. */
|
|
135
|
+
export type SignInContext = Pick<CommandContext, 'overrides' | 'runtime'>;
|
|
136
|
+
/**
|
|
137
|
+
* How to sign in again, to the same app and profile, with a device code where a browser can't
|
|
138
|
+
* finish it.
|
|
139
|
+
*/
|
|
140
|
+
export declare function signInCommand(context: SignInContext, scope: string | null): string;
|
|
141
|
+
/** A word as a shell reads it: quoted unless it is plain. */
|
|
142
|
+
export declare function shellWord(word: string): string;
|
|
143
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/cli/cloud/command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// The shape every cloud command shares: its path, arguments, options and handler.
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
/** A mistake in how the command was called: printed with the command's usage. */
|
|
4
|
+
export class UsageError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'UsageError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export const EXIT_CODES = {
|
|
11
|
+
failed: 1,
|
|
12
|
+
invalid_input: 2,
|
|
13
|
+
needs_confirmation: 4,
|
|
14
|
+
needs_permission: 3,
|
|
15
|
+
needs_sign_in: 3,
|
|
16
|
+
not_found: 5,
|
|
17
|
+
waiting_on_person: 6,
|
|
18
|
+
usage: 2,
|
|
19
|
+
};
|
|
20
|
+
/** What each exit code means; frozen in 2.0 and shown in help. */
|
|
21
|
+
export const EXIT_CODE_MEANINGS = {
|
|
22
|
+
'0': 'done',
|
|
23
|
+
'1': 'failed',
|
|
24
|
+
'2': 'usage or invalid input',
|
|
25
|
+
'3': 'needs sign-in or permission',
|
|
26
|
+
'4': 'needs confirmation: pass --yes once your person has agreed',
|
|
27
|
+
'5': 'not found',
|
|
28
|
+
'6': 'waiting on a person, such as an approval',
|
|
29
|
+
};
|
|
30
|
+
/** A failure that says what kind it is and, where there is one, the command that fixes it. */
|
|
31
|
+
export class CommandFailure extends Error {
|
|
32
|
+
fix;
|
|
33
|
+
kind;
|
|
34
|
+
constructor(kind, message, fix) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.name = 'CommandFailure';
|
|
37
|
+
this.fix = fix;
|
|
38
|
+
this.kind = kind;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** A permission the sign-in lacks: signing in again for `scope` (one, or several comma-separated) fixes it. */
|
|
42
|
+
export class MissingScopeFailure extends CommandFailure {
|
|
43
|
+
scope;
|
|
44
|
+
constructor(context, scope, message) {
|
|
45
|
+
super('needs_permission', message, signInCommand(context, scope));
|
|
46
|
+
this.name = 'MissingScopeFailure';
|
|
47
|
+
this.scope = scope;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function stringOption(input, name) {
|
|
51
|
+
const value = input.values[name];
|
|
52
|
+
return typeof value === 'string' ? value : undefined;
|
|
53
|
+
}
|
|
54
|
+
export function requiredOption(input, name) {
|
|
55
|
+
const value = stringOption(input, name);
|
|
56
|
+
if (value === undefined)
|
|
57
|
+
throw new UsageError(`--${name} is required.`);
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
export function listOption(input, name) {
|
|
61
|
+
const value = input.values[name];
|
|
62
|
+
return Array.isArray(value)
|
|
63
|
+
? value.filter((item) => typeof item === 'string')
|
|
64
|
+
: [];
|
|
65
|
+
}
|
|
66
|
+
export function flag(input, name) {
|
|
67
|
+
return input.values[name] === true;
|
|
68
|
+
}
|
|
69
|
+
export function integerOption(input, name) {
|
|
70
|
+
const value = stringOption(input, name);
|
|
71
|
+
if (value === undefined)
|
|
72
|
+
return undefined;
|
|
73
|
+
const parsed = Number(value);
|
|
74
|
+
if (!Number.isInteger(parsed))
|
|
75
|
+
throw new UsageError(`--${name} must be a whole number.`);
|
|
76
|
+
return parsed;
|
|
77
|
+
}
|
|
78
|
+
export function argument(input, index, name) {
|
|
79
|
+
const value = input.positionals[index];
|
|
80
|
+
if (value === undefined)
|
|
81
|
+
throw new UsageError(`Missing ${name}.`);
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
/** `--limit` and `--after`, which every list takes. */
|
|
85
|
+
export const PAGE_OPTIONS = {
|
|
86
|
+
after: {
|
|
87
|
+
description: 'Start after this cursor, from the previous page.',
|
|
88
|
+
type: 'string',
|
|
89
|
+
valueName: 'CURSOR',
|
|
90
|
+
},
|
|
91
|
+
limit: { description: 'How many to return.', type: 'string', valueName: 'N' },
|
|
92
|
+
};
|
|
93
|
+
export function pageQuery(input) {
|
|
94
|
+
const after = stringOption(input, 'after');
|
|
95
|
+
const limit = integerOption(input, 'limit');
|
|
96
|
+
return {
|
|
97
|
+
...(after === undefined ? {} : { after }),
|
|
98
|
+
...(limit === undefined ? {} : { limit }),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/** `--data <json>` and `--file <path|->`, for request bodies too rich for flags. */
|
|
102
|
+
export const BODY_OPTIONS = {
|
|
103
|
+
data: { description: 'The request body as JSON.', type: 'string', valueName: 'JSON' },
|
|
104
|
+
file: {
|
|
105
|
+
description: 'Read the request body from a JSON file, or - for stdin.',
|
|
106
|
+
type: 'string',
|
|
107
|
+
valueName: 'PATH',
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
/** The JSON body from --data or --file; null when neither was given. */
|
|
111
|
+
export async function readJsonBody(context, input) {
|
|
112
|
+
const data = stringOption(input, 'data');
|
|
113
|
+
const file = stringOption(input, 'file');
|
|
114
|
+
if (data !== undefined && file !== undefined)
|
|
115
|
+
throw new UsageError('Pass --data or --file, not both.');
|
|
116
|
+
const text = data ??
|
|
117
|
+
(file === undefined
|
|
118
|
+
? null
|
|
119
|
+
: file === '-'
|
|
120
|
+
? await context.runtime.readStdin()
|
|
121
|
+
: await readFile(file, 'utf8'));
|
|
122
|
+
if (text === null)
|
|
123
|
+
return null;
|
|
124
|
+
try {
|
|
125
|
+
return JSON.parse(text);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
throw new UsageError(`The request body is not valid JSON${file ? ` (${file})` : ''}.`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export function isJsonObject(value) {
|
|
132
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
133
|
+
}
|
|
134
|
+
/** A value the person types, hidden when secret, or piped on stdin. */
|
|
135
|
+
export async function readValue(context, question, secret) {
|
|
136
|
+
const value = context.runtime.prompt === null
|
|
137
|
+
? (await context.runtime.readStdin()).replace(/\r?\n$/u, '')
|
|
138
|
+
: await context.runtime.prompt(question, { secret });
|
|
139
|
+
if (value.length === 0)
|
|
140
|
+
throw new UsageError('No value was given.');
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
/** Asks yes or no at a terminal; without one, only `--yes` agrees. */
|
|
144
|
+
export async function confirm(context, question) {
|
|
145
|
+
if (context.runtime.prompt === null)
|
|
146
|
+
return false;
|
|
147
|
+
const answer = await context.runtime.prompt(`${question} [y/N] `, { secret: false });
|
|
148
|
+
return /^y(es)?$/iu.test(answer.trim());
|
|
149
|
+
}
|
|
150
|
+
export const YES_OPTION = {
|
|
151
|
+
yes: {
|
|
152
|
+
description: 'Go ahead without being asked. Pass it only once your person has agreed.',
|
|
153
|
+
type: 'boolean',
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Goes ahead with something that asks first: at once with `--yes`, after a yes at a terminal, and
|
|
158
|
+
* otherwise not at all, failing with the command that goes ahead.
|
|
159
|
+
*/
|
|
160
|
+
export async function requireConsent(context, yes, what) {
|
|
161
|
+
if (yes)
|
|
162
|
+
return;
|
|
163
|
+
if (context.runtime.prompt !== null) {
|
|
164
|
+
if (await confirm(context, `${what} Go ahead?`))
|
|
165
|
+
return;
|
|
166
|
+
throw new CommandFailure('needs_confirmation', 'Not done.', null);
|
|
167
|
+
}
|
|
168
|
+
throw new CommandFailure('needs_confirmation', `${what} Run it again with --yes once your person has agreed.`, rerunWith(context, '--yes'));
|
|
169
|
+
}
|
|
170
|
+
/** The command as it was run plus more words, quoted to paste into a shell. */
|
|
171
|
+
export function rerunWith(context, ...extra) {
|
|
172
|
+
return ['dexto', ...context.invocation, ...extra].map(shellWord).join(' ');
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Whether a sign-in here should use a device code: no one is at this terminal, or it is an SSH
|
|
176
|
+
* session, whose loopback redirect a browser on the person's own device can't reach.
|
|
177
|
+
*/
|
|
178
|
+
export function signsInWithDevice(runtime) {
|
|
179
|
+
return (runtime.prompt === null ||
|
|
180
|
+
runtime.environment.SSH_CONNECTION !== undefined ||
|
|
181
|
+
runtime.environment.SSH_TTY !== undefined);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* How to sign in again, to the same app and profile, with a device code where a browser can't
|
|
185
|
+
* finish it.
|
|
186
|
+
*/
|
|
187
|
+
export function signInCommand(context, scope) {
|
|
188
|
+
const profile = context.overrides.profile;
|
|
189
|
+
return [
|
|
190
|
+
'dexto',
|
|
191
|
+
'login',
|
|
192
|
+
...(profile === null ? [] : ['--profile', profile]),
|
|
193
|
+
...(signsInWithDevice(context.runtime) ? ['--device'] : []),
|
|
194
|
+
...(scope === null ? [] : ['--scope', scope]),
|
|
195
|
+
]
|
|
196
|
+
.map(shellWord)
|
|
197
|
+
.join(' ');
|
|
198
|
+
}
|
|
199
|
+
/** A word as a shell reads it: quoted unless it is plain. */
|
|
200
|
+
export function shellWord(word) {
|
|
201
|
+
return /^[\w@%+=:,./-]+$/u.test(word) ? word : `'${word.replaceAll("'", "'\\''")}'`;
|
|
202
|
+
}
|