dexto 1.14.6 → 2.0.0-beta.1
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/agents/coding-agent/coding-agent.yml +0 -2
- package/dist/cli/agent-audit.d.ts +12 -0
- package/dist/cli/agent-audit.d.ts.map +1 -0
- package/dist/cli/agent-audit.js +52 -0
- 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 +107 -0
- package/dist/cli/cloud/command.d.ts.map +1 -0
- package/dist/cli/cloud/command.js +154 -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 +129 -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 +526 -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/artifacts.d.ts +3 -0
- package/dist/cli/cloud/commands/artifacts.d.ts.map +1 -0
- package/dist/cli/cloud/commands/artifacts.js +267 -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 +233 -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 +204 -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 +55 -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 +225 -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 +321 -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 +284 -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 +250 -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 +120 -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 +139 -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 +266 -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 +111 -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 +203 -0
- package/dist/cli/cloud/commands/traces.d.ts +3 -0
- package/dist/cli/cloud/commands/traces.d.ts.map +1 -0
- package/dist/cli/cloud/commands/traces.js +142 -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 +657 -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 +281 -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 +109 -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 +77 -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 +36 -0
- package/dist/cli/cloud/v1.d.ts +20 -0
- package/dist/cli/cloud/v1.d.ts.map +1 -0
- package/dist/cli/cloud/v1.js +66 -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 +248 -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 +44 -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.d.ts.map +1 -1
- package/dist/cli/commands/run/headless.js +57 -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/run/step-log.d.ts +11 -0
- package/dist/cli/commands/run/step-log.d.ts.map +1 -0
- package/dist/cli/commands/run/step-log.js +42 -0
- 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/failure.d.ts +29 -0
- package/dist/cli/failure.d.ts.map +1 -0
- package/dist/cli/failure.js +31 -0
- 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/import/claude-code.d.ts +10 -0
- package/dist/cli/import/claude-code.d.ts.map +1 -0
- package/dist/cli/import/claude-code.js +131 -0
- package/dist/cli/import/codex.d.ts +27 -0
- package/dist/cli/import/codex.d.ts.map +1 -0
- package/dist/cli/import/codex.js +148 -0
- package/dist/cli/import/git.d.ts +19 -0
- package/dist/cli/import/git.d.ts.map +1 -0
- package/dist/cli/import/git.js +95 -0
- package/dist/cli/import/local-chats.d.ts +28 -0
- package/dist/cli/import/local-chats.d.ts.map +1 -0
- package/dist/cli/import/local-chats.js +129 -0
- package/dist/cli/import/redaction.d.ts +37 -0
- package/dist/cli/import/redaction.d.ts.map +1 -0
- package/dist/cli/import/redaction.js +148 -0
- package/dist/cli/import/test-utils.d.ts +16 -0
- package/dist/cli/import/test-utils.d.ts.map +1 -0
- package/dist/cli/import/test-utils.js +223 -0
- package/dist/cli/import/transcript.d.ts +75 -0
- package/dist/cli/import/transcript.d.ts.map +1 -0
- package/dist/cli/import/transcript.js +123 -0
- package/dist/cli/interaction.d.ts +18 -0
- package/dist/cli/interaction.d.ts.map +1 -0
- package/dist/cli/interaction.js +30 -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/output.d.ts +9 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +6 -0
- 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 +44 -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
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { CloudRuntime } from './runtime.js';
|
|
2
|
+
export interface Column<Row> {
|
|
3
|
+
readonly header: string;
|
|
4
|
+
readonly value: (row: Row) => string | number | boolean | null | undefined;
|
|
5
|
+
}
|
|
6
|
+
export interface Output {
|
|
7
|
+
/** Whether records and lists print as JSON. */
|
|
8
|
+
readonly json: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Whether content, such as a file, a command's output or a model's reply, prints as its JSON
|
|
11
|
+
* record: only with an explicit --json, so piped content stays intact.
|
|
12
|
+
*/
|
|
13
|
+
readonly jsonContent: boolean;
|
|
14
|
+
/** A page of a list: a table, plus how to read the next page when there is one. */
|
|
15
|
+
list<Row>(page: ListPage<Row>, columns: readonly Column<Row>[]): void;
|
|
16
|
+
/** One resource: its fields, one per line. */
|
|
17
|
+
record(value: unknown): void;
|
|
18
|
+
/** A line for people; JSON output prints the value instead. */
|
|
19
|
+
result(value: unknown, text: string): void;
|
|
20
|
+
/** Progress and hints, on stderr so stdout stays parseable. */
|
|
21
|
+
note(text: string): void;
|
|
22
|
+
}
|
|
23
|
+
/** A list, paged or not: some `/v1` lists return everything at once. */
|
|
24
|
+
export type ListPage<Row> = {
|
|
25
|
+
readonly data: readonly Row[];
|
|
26
|
+
} | {
|
|
27
|
+
readonly data: readonly Row[];
|
|
28
|
+
readonly has_more: boolean;
|
|
29
|
+
readonly next_after: string | number | null;
|
|
30
|
+
};
|
|
31
|
+
/** `json` and `table` as asked; `auto` is tables at a terminal and JSON anywhere else. */
|
|
32
|
+
export type OutputFormat = 'auto' | 'json' | 'table';
|
|
33
|
+
export declare function createOutput(runtime: CloudRuntime, format: OutputFormat): Output;
|
|
34
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/cli/cloud/output.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,WAAW,MAAM,CAAC,GAAG;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;CAC9E;AAED,MAAM,WAAW,MAAM;IACnB,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,mFAAmF;IACnF,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,SAAS,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC;IACtE,8CAA8C;IAC9C,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,+DAA+D;IAC/D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3C,+DAA+D;IAC/D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wEAAwE;AACxE,MAAM,MAAM,QAAQ,CAAC,GAAG,IAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAA;CAAE,GACjC;IACI,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC/C,CAAC;AAER,0FAA0F;AAC1F,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAErD,wBAAgB,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAiChF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Prints API values: JSON for agents (--json, or stdout not a terminal), tables for people.
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { jsonResult } from '../output.js';
|
|
4
|
+
export function createOutput(runtime, format) {
|
|
5
|
+
const json = format === 'json' || (format === 'auto' && !runtime.stdoutIsTerminal);
|
|
6
|
+
const color = runtime.color;
|
|
7
|
+
const printJson = (value) => {
|
|
8
|
+
runtime.writeOutput(jsonResult(value));
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
json,
|
|
12
|
+
jsonContent: format === 'json',
|
|
13
|
+
list(page, columns) {
|
|
14
|
+
if (json)
|
|
15
|
+
return printJson(page);
|
|
16
|
+
if (page.data.length === 0) {
|
|
17
|
+
runtime.writeOutput(`${dim('None.', color)}\n`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
runtime.writeOutput(renderTable(page.data, columns, color));
|
|
21
|
+
if ('next_after' in page && page.has_more && page.next_after !== null)
|
|
22
|
+
runtime.writeError(`${dim(`More results: add --after ${String(page.next_after)}`, color)}\n`);
|
|
23
|
+
},
|
|
24
|
+
note(text) {
|
|
25
|
+
runtime.writeError(`${dim(text, color)}\n`);
|
|
26
|
+
},
|
|
27
|
+
record(value) {
|
|
28
|
+
if (json)
|
|
29
|
+
return printJson(value);
|
|
30
|
+
runtime.writeOutput(renderRecord(value, color));
|
|
31
|
+
},
|
|
32
|
+
result(value, text) {
|
|
33
|
+
if (json)
|
|
34
|
+
return printJson(value);
|
|
35
|
+
runtime.writeOutput(`${text}\n`);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function renderTable(rows, columns, color) {
|
|
40
|
+
const cells = rows.map((row) => columns.map((column) => cell(column.value(row))));
|
|
41
|
+
const widths = columns.map((column, index) => Math.max(column.header.length, ...cells.map((row) => (row[index] ?? '').length)));
|
|
42
|
+
const line = (values) => values
|
|
43
|
+
.map((value, index) => index === values.length - 1 ? value : value.padEnd(widths[index] ?? 0))
|
|
44
|
+
.join(' ')
|
|
45
|
+
.trimEnd();
|
|
46
|
+
const header = line(columns.map((column) => column.header.toUpperCase()));
|
|
47
|
+
return `${color ? chalk.bold(header) : header}\n${cells.map(line).join('\n')}\n`;
|
|
48
|
+
}
|
|
49
|
+
/** Top-level fields aligned; nested values as compact JSON. */
|
|
50
|
+
function renderRecord(value, color) {
|
|
51
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
52
|
+
return `${JSON.stringify(value, null, 2)}\n`;
|
|
53
|
+
const entries = Object.entries(value);
|
|
54
|
+
const width = Math.max(...entries.map(([key]) => key.length));
|
|
55
|
+
return `${entries
|
|
56
|
+
.map(([key, field]) => `${dim(key.padEnd(width), color)} ${recordField(field)}`)
|
|
57
|
+
.join('\n')}\n`;
|
|
58
|
+
}
|
|
59
|
+
function recordField(value) {
|
|
60
|
+
if (value === null)
|
|
61
|
+
return '-';
|
|
62
|
+
if (typeof value === 'string')
|
|
63
|
+
return value.includes('\n') ? JSON.stringify(value) : value;
|
|
64
|
+
if (typeof value === 'number' || typeof value === 'boolean')
|
|
65
|
+
return String(value);
|
|
66
|
+
return JSON.stringify(value);
|
|
67
|
+
}
|
|
68
|
+
const MAX_CELL = 60;
|
|
69
|
+
function cell(value) {
|
|
70
|
+
if (value === null || value === undefined)
|
|
71
|
+
return '-';
|
|
72
|
+
const text = String(value).replace(/\s+/gu, ' ');
|
|
73
|
+
return text.length > MAX_CELL ? `${text.slice(0, MAX_CELL - 1)}…` : text;
|
|
74
|
+
}
|
|
75
|
+
function dim(text, color) {
|
|
76
|
+
return color ? chalk.dim(text) : text;
|
|
77
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Command, type OptionSpec } from './command.js';
|
|
2
|
+
import type { SignInFor } from './commands/account.js';
|
|
3
|
+
import type { Connection, ConnectionOverrides } from './connection.js';
|
|
4
|
+
import type { CloudRuntime } from './runtime.js';
|
|
5
|
+
/** One area of commands in help, such as `projects` under `cloud`. */
|
|
6
|
+
export interface Group {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly summary: string;
|
|
9
|
+
}
|
|
10
|
+
/** What the commands run against: injected so tests use a fake server and sign-in. */
|
|
11
|
+
export interface CloudHost {
|
|
12
|
+
readonly commands: readonly Command[];
|
|
13
|
+
/** Help's areas by the words before them, such as `cloud`. */
|
|
14
|
+
readonly groups: Readonly<Record<string, readonly Group[]>>;
|
|
15
|
+
readonly runtime: CloudRuntime;
|
|
16
|
+
/** The connection for these overrides; null when signed out. */
|
|
17
|
+
readonly resolveConnection: (overrides: ConnectionOverrides) => Promise<Connection | null>;
|
|
18
|
+
/** The sign-in context login, logout, whoami and accounts run in. */
|
|
19
|
+
readonly signIn: SignInFor;
|
|
20
|
+
/** Signs the profile in again asking for `scope`; true once it did. */
|
|
21
|
+
readonly signInForScope: (overrides: ConnectionOverrides, scope: string) => Promise<boolean>;
|
|
22
|
+
}
|
|
23
|
+
export declare const GLOBAL_OPTIONS: Readonly<Record<string, OptionSpec>>;
|
|
24
|
+
/** Runs one command line, such as `cloud secrets list --json`; returns its exit code. */
|
|
25
|
+
export declare function runCloud(host: CloudHost, argv: readonly string[]): Promise<number>;
|
|
26
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/cloud/run.ts"],"names":[],"mappings":"AAQA,OAAO,EAIH,KAAK,OAAO,EAEZ,KAAK,UAAU,EAElB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAOvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,sEAAsE;AACtE,MAAM,WAAW,KAAK;IAClB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC5B;AAED,sFAAsF;AACtF,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC;IAC5D,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,gEAAgE;IAChE,QAAQ,CAAC,iBAAiB,EAAE,CAAC,SAAS,EAAE,mBAAmB,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAC3F,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAChG;AAED,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAgC/D,CAAC;AASF,yFAAyF;AACzF,wBAAsB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAExF"}
|
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
// Runs `dexto cloud …` and the other ported cloud commands: global options, help, the agent
|
|
2
|
+
// contract's JSON output and exit codes, and signing in again for a permission a command lacked.
|
|
3
|
+
import { CommandFailure, EXIT_CODE_MEANINGS, EXIT_CODES } from '../failure.js';
|
|
4
|
+
import { parseArgs } from 'node:util';
|
|
5
|
+
import { jsonError } from '../output.js';
|
|
6
|
+
import { CloudApiError, createCloudClient } from '@dexto/cloud-client';
|
|
7
|
+
import { MissingScopeFailure, signInCommand, UsageError, } from './command.js';
|
|
8
|
+
import { listWorkspaceApps, runWorkspaceApp, } from './commands/workspace-apps.js';
|
|
9
|
+
import { createOutput } from './output.js';
|
|
10
|
+
export const GLOBAL_OPTIONS = {
|
|
11
|
+
'api-base-url': {
|
|
12
|
+
description: 'The API origin (default https://api.dexto.ai, or DEXTO_API_BASE_URL).',
|
|
13
|
+
type: 'string',
|
|
14
|
+
valueName: 'URL',
|
|
15
|
+
},
|
|
16
|
+
'api-key': {
|
|
17
|
+
description: 'Use this key instead of DEXTO_API_KEY or the saved sign-in.',
|
|
18
|
+
type: 'string',
|
|
19
|
+
valueName: 'KEY',
|
|
20
|
+
},
|
|
21
|
+
profile: {
|
|
22
|
+
description: 'The saved sign-in to use for this run (or DEXTO_PROFILE); see dexto accounts list.',
|
|
23
|
+
type: 'string',
|
|
24
|
+
valueName: 'NAME',
|
|
25
|
+
},
|
|
26
|
+
project: {
|
|
27
|
+
description: "The Cloud project to act in when you're signed in (or DEXTO_CLOUD_PROJECT).",
|
|
28
|
+
type: 'string',
|
|
29
|
+
valueName: 'ID',
|
|
30
|
+
},
|
|
31
|
+
help: { description: 'Show help.', short: 'h', type: 'boolean' },
|
|
32
|
+
json: {
|
|
33
|
+
description: "Print JSON, failures included (on stderr). The default when stdout isn't a terminal.",
|
|
34
|
+
type: 'boolean',
|
|
35
|
+
},
|
|
36
|
+
table: {
|
|
37
|
+
description: "Print tables for people even when stdout isn't a terminal.",
|
|
38
|
+
type: 'boolean',
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
const NO_OVERRIDES = {
|
|
42
|
+
apiBaseUrl: null,
|
|
43
|
+
apiKey: null,
|
|
44
|
+
cloudProject: null,
|
|
45
|
+
profile: null,
|
|
46
|
+
};
|
|
47
|
+
/** Runs one command line, such as `cloud secrets list --json`; returns its exit code. */
|
|
48
|
+
export async function runCloud(host, argv) {
|
|
49
|
+
return await run(host, argv, true);
|
|
50
|
+
}
|
|
51
|
+
async function run(host, argv, mayGrant) {
|
|
52
|
+
const { runtime } = host;
|
|
53
|
+
let globals;
|
|
54
|
+
try {
|
|
55
|
+
globals = extractGlobals(argv);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
// The format isn't settled yet: JSON as asked, or when no one reads stdout.
|
|
59
|
+
return reportError({ overrides: NO_OVERRIDES, runtime }, argv.includes('--json') || !runtime.stdoutIsTerminal, groupHelp(host, argv.slice(0, 1)), error);
|
|
60
|
+
}
|
|
61
|
+
const { command, words, rest } = matchCommand(host.commands, globals.rest);
|
|
62
|
+
// `workspace` alone lists the apps; `workspace <app> …` is one of them, its operations from the
|
|
63
|
+
// server. The CLI's own `workspace` commands, such as `tools` and `drive put`, match above.
|
|
64
|
+
if (command === null && words[0] === 'workspace')
|
|
65
|
+
return await runWorkspace(host, globals, argv, mayGrant);
|
|
66
|
+
if (command === null) {
|
|
67
|
+
if (!host.commands.some((each) => startsWith(each.path, words)))
|
|
68
|
+
return reportError({ overrides: globals.overrides, runtime }, createOutput(runtime, globals.format).json, groupHelp(host, words.slice(0, 1)), new UsageError(`Unknown command: dexto ${words.join(' ')}`));
|
|
69
|
+
return printHelp(runtime, globals, groupHelp(host, words), groupHelpJson(host, words));
|
|
70
|
+
}
|
|
71
|
+
if (globals.help)
|
|
72
|
+
return printHelp(runtime, globals, commandHelp(command), commandHelpJson(command));
|
|
73
|
+
const output = createOutput(runtime, globals.format);
|
|
74
|
+
const signIn = { overrides: globals.overrides, runtime };
|
|
75
|
+
try {
|
|
76
|
+
const parsed = parseArgs({
|
|
77
|
+
allowPositionals: true,
|
|
78
|
+
args: [...rest],
|
|
79
|
+
options: Object.fromEntries(Object.entries(command.options ?? {}).map(([name, spec]) => [
|
|
80
|
+
name,
|
|
81
|
+
{
|
|
82
|
+
type: spec.type,
|
|
83
|
+
...(spec.multiple === true ? { multiple: true } : {}),
|
|
84
|
+
...(spec.short === undefined ? {} : { short: spec.short }),
|
|
85
|
+
},
|
|
86
|
+
])),
|
|
87
|
+
strict: true,
|
|
88
|
+
});
|
|
89
|
+
const required = (command.arguments ?? '').match(/<[^>]+>/gu)?.length ?? 0;
|
|
90
|
+
if (parsed.positionals.length < required)
|
|
91
|
+
throw new UsageError(`Missing arguments: ${command.arguments ?? ''}`);
|
|
92
|
+
return (await command.run(contextFor(host, globals, output), parsed)) ?? 0;
|
|
93
|
+
}
|
|
94
|
+
catch (thrown) {
|
|
95
|
+
const error = asMissingScope(signIn, thrown);
|
|
96
|
+
if (mayGrant &&
|
|
97
|
+
error instanceof MissingScopeFailure &&
|
|
98
|
+
runtime.prompt !== null &&
|
|
99
|
+
!output.json &&
|
|
100
|
+
(await askToGrant(host, globals.overrides, error)))
|
|
101
|
+
return await run(host, argv, false);
|
|
102
|
+
return reportError(signIn, output.json, commandHelp(command), error);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** `workspace` or `workspace <app> [operation] [action] [--field value…]`. */
|
|
106
|
+
async function runWorkspace(host, globals, argv, mayGrant) {
|
|
107
|
+
const output = createOutput(host.runtime, globals.format);
|
|
108
|
+
const context = contextFor(host, globals, output);
|
|
109
|
+
const args = globals.rest.slice(1);
|
|
110
|
+
try {
|
|
111
|
+
if (args.every((arg) => arg.startsWith('-'))) {
|
|
112
|
+
const apps = await listWorkspaceApps(context);
|
|
113
|
+
return printHelp(host.runtime, globals, workspaceHelp(host, apps), {
|
|
114
|
+
apps,
|
|
115
|
+
...groupHelpJson(host, ['workspace']),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
const appId = args[0] ?? '';
|
|
119
|
+
return await runWorkspaceApp(context, args, globals.help, host.commands
|
|
120
|
+
.filter((each) => each.path[0] === 'workspace' && each.path[1] === appId)
|
|
121
|
+
.map((each) => ({
|
|
122
|
+
name: each.path.slice(2).join(' '),
|
|
123
|
+
summary: each.summary,
|
|
124
|
+
usage: `dexto ${usage(each)}`,
|
|
125
|
+
})));
|
|
126
|
+
}
|
|
127
|
+
catch (thrown) {
|
|
128
|
+
const error = asMissingScope(context, thrown);
|
|
129
|
+
if (mayGrant &&
|
|
130
|
+
error instanceof MissingScopeFailure &&
|
|
131
|
+
host.runtime.prompt !== null &&
|
|
132
|
+
!output.json &&
|
|
133
|
+
(await askToGrant(host, globals.overrides, error)))
|
|
134
|
+
return await run(host, argv, false);
|
|
135
|
+
return reportError(context, output.json, workspaceHelp(host, null), error);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** The workspace's apps, when listed, and the CLI's own workspace commands. */
|
|
139
|
+
function workspaceHelp(host, apps) {
|
|
140
|
+
const commands = host.commands.filter((command) => command.path[0] === 'workspace');
|
|
141
|
+
const usages = commands.map((command) => usage(command));
|
|
142
|
+
const width = Math.max(...usages.map((line) => line.length));
|
|
143
|
+
return [
|
|
144
|
+
'Usage: dexto workspace <app> [operation] [--field value…] [--yes]',
|
|
145
|
+
' dexto workspace <command>',
|
|
146
|
+
'',
|
|
147
|
+
'Use your Dexto workspace as yourself: the apps and tools your agents use over the Dexto MCP.',
|
|
148
|
+
'',
|
|
149
|
+
"Your workspace's apps (dexto workspace <app> lists what each does):",
|
|
150
|
+
...(apps === null
|
|
151
|
+
? [' Run dexto workspace while signed in to list them.']
|
|
152
|
+
: apps.length === 0
|
|
153
|
+
? [' None yet.']
|
|
154
|
+
: [` ${apps.map((app) => app.id).join(' · ')}`]),
|
|
155
|
+
'',
|
|
156
|
+
'Commands:',
|
|
157
|
+
...commands.map((command, index) => ` ${(usages[index] ?? '').padEnd(width)} ${command.summary}`),
|
|
158
|
+
'',
|
|
159
|
+
'Find what to run: dexto find "<what you want to do>"',
|
|
160
|
+
'',
|
|
161
|
+
].join('\n');
|
|
162
|
+
}
|
|
163
|
+
/** At a terminal, offers to sign in again for the permission; true once that sign-in succeeded. */
|
|
164
|
+
async function askToGrant(host, overrides, error) {
|
|
165
|
+
const answer = (await host.runtime.prompt?.(`${error.message} Sign in again to grant it? [y/N] `, {
|
|
166
|
+
secret: false,
|
|
167
|
+
})) ?? '';
|
|
168
|
+
if (!/^y(es)?$/iu.test(answer.trim()))
|
|
169
|
+
return false;
|
|
170
|
+
return await host.signInForScope(overrides, error.scope);
|
|
171
|
+
}
|
|
172
|
+
function contextFor(host, globals, output) {
|
|
173
|
+
const { overrides } = globals;
|
|
174
|
+
const connection = async () => {
|
|
175
|
+
const resolved = await host.resolveConnection(overrides);
|
|
176
|
+
if (resolved !== null)
|
|
177
|
+
return resolved;
|
|
178
|
+
throw new CommandFailure('needs_sign_in', 'Not signed in. Sign in, or set DEXTO_API_KEY to a developer key from your Cloud project.', signInCommand({ overrides, runtime: host.runtime }, null));
|
|
179
|
+
};
|
|
180
|
+
return {
|
|
181
|
+
client: async () => {
|
|
182
|
+
const resolved = await connection();
|
|
183
|
+
return createCloudClient({
|
|
184
|
+
apiBaseUrl: resolved.apiBaseUrl,
|
|
185
|
+
token: resolved.token,
|
|
186
|
+
// A key acts in its own project; only a person's token names one.
|
|
187
|
+
cloudProject: resolved.kind === 'oauth' ? resolved.cloudProject : null,
|
|
188
|
+
fetch: host.runtime.fetch,
|
|
189
|
+
});
|
|
190
|
+
},
|
|
191
|
+
connection,
|
|
192
|
+
invocation: globals.invocation,
|
|
193
|
+
output,
|
|
194
|
+
overrides,
|
|
195
|
+
runtime: host.runtime,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/** A `/v1` refusal that names the scope the sign-in lacks; any other error as it is. */
|
|
199
|
+
function asMissingScope(context, error) {
|
|
200
|
+
if (!(error instanceof CloudApiError) || error.status !== 403)
|
|
201
|
+
return error;
|
|
202
|
+
const details = error.details;
|
|
203
|
+
const scope = typeof details === 'object' && details !== null && 'scope' in details
|
|
204
|
+
? details.scope
|
|
205
|
+
: undefined;
|
|
206
|
+
if (typeof scope !== 'string')
|
|
207
|
+
return error;
|
|
208
|
+
return new MissingScopeFailure(context, scope, error.message);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Prints a failure and returns its exit code: JSON on stderr for agents, otherwise a message with
|
|
212
|
+
* the command's usage (for a usage mistake) or the command that fixes it.
|
|
213
|
+
*/
|
|
214
|
+
function reportError(context, json, help, error) {
|
|
215
|
+
const { runtime } = context;
|
|
216
|
+
const failure = describeFailure(context, error);
|
|
217
|
+
if (json) {
|
|
218
|
+
runtime.writeError(jsonError({
|
|
219
|
+
code: failure.code,
|
|
220
|
+
message: failure.message,
|
|
221
|
+
...(failure.fix === null ? {} : { fix: failure.fix }),
|
|
222
|
+
...(failure.apiCode === null ? {} : { api_code: failure.apiCode }),
|
|
223
|
+
...(failure.details === null ? {} : { details: failure.details }),
|
|
224
|
+
}));
|
|
225
|
+
}
|
|
226
|
+
else if (failure.code === 'usage') {
|
|
227
|
+
runtime.writeError(`${failure.message}\n\n${help}`);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
runtime.writeError(`Error${failure.apiCode === null ? '' : ` (${failure.apiCode})`}: ${failure.message}\n`);
|
|
231
|
+
if (failure.details !== null)
|
|
232
|
+
runtime.writeError(`${JSON.stringify(failure.details, null, 2)}\n`);
|
|
233
|
+
if (failure.fix !== null)
|
|
234
|
+
runtime.writeError(`Run: ${failure.fix}\n`);
|
|
235
|
+
}
|
|
236
|
+
return EXIT_CODES[failure.code];
|
|
237
|
+
}
|
|
238
|
+
function describeFailure(context, error) {
|
|
239
|
+
const report = (code, message, fix, apiCode, details) => ({ apiCode, code, details: details ?? null, fix, message });
|
|
240
|
+
if (error instanceof UsageError || isParseArgsError(error))
|
|
241
|
+
return report('usage', error.message, null, null, null);
|
|
242
|
+
if (error instanceof CommandFailure)
|
|
243
|
+
return report(error.kind, error.message, error.fix, null, null);
|
|
244
|
+
if (error instanceof CloudApiError) {
|
|
245
|
+
if (error.status === 401)
|
|
246
|
+
return report('needs_sign_in', error.message, signInCommand(context, null), error.code, error.details);
|
|
247
|
+
return report(error.status === 403
|
|
248
|
+
? 'needs_permission'
|
|
249
|
+
: error.status === 404
|
|
250
|
+
? 'not_found'
|
|
251
|
+
: error.status === 400 || error.status === 413 || error.status === 422
|
|
252
|
+
? 'invalid_input'
|
|
253
|
+
: 'failed', error.message, null, error.code, error.details);
|
|
254
|
+
}
|
|
255
|
+
if (error instanceof Error)
|
|
256
|
+
return report('failed', error.message, null, null, null);
|
|
257
|
+
return report('failed', 'The command failed.', null, null, null);
|
|
258
|
+
}
|
|
259
|
+
/** Takes the global options out wherever they appear, before the command's own parsing. */
|
|
260
|
+
function extractGlobals(argv) {
|
|
261
|
+
const rest = [];
|
|
262
|
+
let apiBaseUrl = null;
|
|
263
|
+
let apiKey = null;
|
|
264
|
+
let cloudProject = null;
|
|
265
|
+
let profile = null;
|
|
266
|
+
let help = false;
|
|
267
|
+
let json = false;
|
|
268
|
+
let table = false;
|
|
269
|
+
const invocation = [];
|
|
270
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
271
|
+
const token = argv[index] ?? '';
|
|
272
|
+
if (token === '--') {
|
|
273
|
+
rest.push(...argv.slice(index));
|
|
274
|
+
invocation.push(...argv.slice(index));
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
const [name, inline] = token.startsWith('--') ? splitOption(token) : [token, null];
|
|
278
|
+
if (name === '--api-key' ||
|
|
279
|
+
name === '--api-base-url' ||
|
|
280
|
+
name === '--profile' ||
|
|
281
|
+
name === '--project') {
|
|
282
|
+
const value = inline ?? argv[index + 1];
|
|
283
|
+
// Never take another option as the value, so `--project --api-key KEY` can't leave
|
|
284
|
+
// the key behind as a word that gets printed back.
|
|
285
|
+
if (value === undefined || (inline === null && value.startsWith('-')))
|
|
286
|
+
throw new UsageError(`Missing value for ${name}.`);
|
|
287
|
+
if (inline === null)
|
|
288
|
+
index += 1;
|
|
289
|
+
if (name === '--api-key')
|
|
290
|
+
apiKey = value;
|
|
291
|
+
else {
|
|
292
|
+
invocation.push(name, value);
|
|
293
|
+
if (name === '--project')
|
|
294
|
+
cloudProject = value;
|
|
295
|
+
else if (name === '--profile')
|
|
296
|
+
profile = value;
|
|
297
|
+
else
|
|
298
|
+
apiBaseUrl = value;
|
|
299
|
+
}
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (token === '--json')
|
|
303
|
+
json = true;
|
|
304
|
+
else if (token === '--table')
|
|
305
|
+
table = true;
|
|
306
|
+
else if (token === '--help' || token === '-h')
|
|
307
|
+
help = true;
|
|
308
|
+
else
|
|
309
|
+
rest.push(token);
|
|
310
|
+
if (token !== '--help' && token !== '-h')
|
|
311
|
+
invocation.push(token);
|
|
312
|
+
}
|
|
313
|
+
if (json && table)
|
|
314
|
+
throw new UsageError('Pass --json or --table, not both.');
|
|
315
|
+
return {
|
|
316
|
+
format: json ? 'json' : table ? 'table' : 'auto',
|
|
317
|
+
help,
|
|
318
|
+
invocation,
|
|
319
|
+
overrides: { apiBaseUrl, apiKey, cloudProject, profile },
|
|
320
|
+
rest,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function splitOption(token) {
|
|
324
|
+
const equals = token.indexOf('=');
|
|
325
|
+
return equals === -1 ? [token, null] : [token.slice(0, equals), token.slice(equals + 1)];
|
|
326
|
+
}
|
|
327
|
+
/** The longest command whose path the leading words spell. */
|
|
328
|
+
function matchCommand(commands, tokens) {
|
|
329
|
+
const words = [];
|
|
330
|
+
for (const token of tokens) {
|
|
331
|
+
if (token.startsWith('-'))
|
|
332
|
+
break;
|
|
333
|
+
const next = [...words, token];
|
|
334
|
+
if (!commands.some((command) => startsWith(command.path, next)))
|
|
335
|
+
break;
|
|
336
|
+
words.push(token);
|
|
337
|
+
}
|
|
338
|
+
for (let length = words.length; length > 0; length -= 1) {
|
|
339
|
+
const prefix = words.slice(0, length);
|
|
340
|
+
const command = commands.find((each) => each.path.length === length && startsWith(each.path, prefix));
|
|
341
|
+
if (command !== undefined)
|
|
342
|
+
return { command, rest: tokens.slice(length), words: prefix };
|
|
343
|
+
}
|
|
344
|
+
const rest = tokens.slice(words.length);
|
|
345
|
+
// A word after a group that names none of its commands, such as `cloud chat`, is unknown.
|
|
346
|
+
const unknown = rest[0] !== undefined && !rest[0].startsWith('-') ? [rest[0]] : [];
|
|
347
|
+
return {
|
|
348
|
+
command: null,
|
|
349
|
+
rest,
|
|
350
|
+
words: words.length === 0
|
|
351
|
+
? tokens.filter((token) => !token.startsWith('-'))
|
|
352
|
+
: [...words, ...unknown],
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function startsWith(path, prefix) {
|
|
356
|
+
return prefix.every((word, index) => path[index] === word);
|
|
357
|
+
}
|
|
358
|
+
/** Help as text for people, or as JSON where the output is JSON. */
|
|
359
|
+
function printHelp(runtime, globals, text, json) {
|
|
360
|
+
if (createOutput(runtime, globals.format).json)
|
|
361
|
+
runtime.writeOutput(`${JSON.stringify(json, null, 2)}\n`);
|
|
362
|
+
else
|
|
363
|
+
runtime.writeOutput(text);
|
|
364
|
+
return 0;
|
|
365
|
+
}
|
|
366
|
+
/** A layer's own areas when it has them, otherwise its commands with their usage. */
|
|
367
|
+
function groupHelp(host, words) {
|
|
368
|
+
const areas = host.groups[words.join(' ')];
|
|
369
|
+
if (areas !== undefined) {
|
|
370
|
+
const width = Math.max(...areas.map((group) => group.name.length));
|
|
371
|
+
return [
|
|
372
|
+
`Usage: dexto ${words.join(' ')} <command>`,
|
|
373
|
+
'',
|
|
374
|
+
'Commands:',
|
|
375
|
+
...areas.map((group) => ` ${group.name.padEnd(width)} ${group.summary}`),
|
|
376
|
+
'',
|
|
377
|
+
'Global options:',
|
|
378
|
+
...optionLines(GLOBAL_OPTIONS),
|
|
379
|
+
'',
|
|
380
|
+
"Output is JSON when stdout isn't a terminal; a failure's JSON on stderr names the command",
|
|
381
|
+
'that fixes it. Exit codes: 0 done, 1 failed, 2 usage, 3 needs sign-in or permission,',
|
|
382
|
+
'4 needs --yes (pass it only once your person has agreed), 5 not found, 6 waiting on a',
|
|
383
|
+
'person (such as an approval).',
|
|
384
|
+
'',
|
|
385
|
+
].join('\n');
|
|
386
|
+
}
|
|
387
|
+
const commands = host.commands.filter((command) => startsWith(command.path, words));
|
|
388
|
+
const usages = commands.map((command) => usage(command));
|
|
389
|
+
const width = Math.max(...usages.map((line) => line.length));
|
|
390
|
+
return [
|
|
391
|
+
`Usage: dexto ${words.join(' ')} <command>`,
|
|
392
|
+
'',
|
|
393
|
+
'Commands:',
|
|
394
|
+
...commands.map((command, index) => ` ${(usages[index] ?? '').padEnd(width)} ${command.summary}`),
|
|
395
|
+
'',
|
|
396
|
+
].join('\n');
|
|
397
|
+
}
|
|
398
|
+
function groupHelpJson(host, words) {
|
|
399
|
+
return {
|
|
400
|
+
commands: host.commands
|
|
401
|
+
.filter((command) => startsWith(command.path, words))
|
|
402
|
+
.map((command) => ({ summary: command.summary, usage: `dexto ${usage(command)}` })),
|
|
403
|
+
exit_codes: EXIT_CODE_MEANINGS,
|
|
404
|
+
usage: `dexto ${words.join(' ')} <command>`,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
function commandHelp(command) {
|
|
408
|
+
return [
|
|
409
|
+
`Usage: dexto ${usage(command)}${command.options === undefined ? '' : ' [options]'}`,
|
|
410
|
+
'',
|
|
411
|
+
command.summary,
|
|
412
|
+
'',
|
|
413
|
+
...(command.options === undefined ? [] : ['Options:', ...optionLines(command.options), '']),
|
|
414
|
+
'Global options:',
|
|
415
|
+
...optionLines(GLOBAL_OPTIONS),
|
|
416
|
+
'',
|
|
417
|
+
].join('\n');
|
|
418
|
+
}
|
|
419
|
+
function commandHelpJson(command) {
|
|
420
|
+
return {
|
|
421
|
+
options: Object.entries({ ...command.options, ...GLOBAL_OPTIONS }).map(([name, spec]) => ({
|
|
422
|
+
description: spec.description,
|
|
423
|
+
name: `--${name}`,
|
|
424
|
+
type: spec.type,
|
|
425
|
+
...(spec.multiple === true ? { multiple: true } : {}),
|
|
426
|
+
})),
|
|
427
|
+
summary: command.summary,
|
|
428
|
+
usage: `dexto ${usage(command)}`,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function usage(command) {
|
|
432
|
+
return [...command.path, ...(command.arguments === undefined ? [] : [command.arguments])].join(' ');
|
|
433
|
+
}
|
|
434
|
+
function optionLines(options) {
|
|
435
|
+
const labels = Object.entries(options).map(([name, spec]) => `${spec.short === undefined ? ' ' : `-${spec.short}, `}--${name}${spec.type === 'string' ? ` ${spec.valueName ?? 'VALUE'}` : ''}${spec.multiple === true ? ' ...' : ''}`);
|
|
436
|
+
const width = Math.max(...labels.map((label) => label.length));
|
|
437
|
+
return Object.values(options).map((spec, index) => ` ${(labels[index] ?? '').padEnd(width)} ${spec.description}`);
|
|
438
|
+
}
|
|
439
|
+
function isParseArgsError(error) {
|
|
440
|
+
return (error instanceof Error &&
|
|
441
|
+
'code' in error &&
|
|
442
|
+
typeof error.code === 'string' &&
|
|
443
|
+
error.code.startsWith('ERR_PARSE_ARGS_'));
|
|
444
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface CloudRuntime {
|
|
2
|
+
/** Whether to color what people read: a terminal that shows colors. */
|
|
3
|
+
readonly color: boolean;
|
|
4
|
+
readonly environment: Readonly<Record<string, string | undefined>>;
|
|
5
|
+
readonly fetch: typeof globalThis.fetch;
|
|
6
|
+
/** Where other agents keep their chats, such as ~/.claude and ~/.codex. */
|
|
7
|
+
readonly homeDirectory: string;
|
|
8
|
+
/** Asks the person at the terminal; null when stdin is not a terminal. */
|
|
9
|
+
readonly prompt: ((question: string, options: {
|
|
10
|
+
secret: boolean;
|
|
11
|
+
}) => Promise<string>) | null;
|
|
12
|
+
/** All of stdin as text, for piped input. */
|
|
13
|
+
readonly readStdin: () => Promise<string>;
|
|
14
|
+
/** Runs a program, such as a project's packer, and returns its exit code and what it printed. */
|
|
15
|
+
readonly runProcess: (command: string, args: readonly string[], options: {
|
|
16
|
+
readonly cwd: string;
|
|
17
|
+
}) => Promise<ProcessResult>;
|
|
18
|
+
readonly signal: AbortSignal;
|
|
19
|
+
/** Waits, ending early with an error when the command is cancelled. */
|
|
20
|
+
readonly sleep: (ms: number) => Promise<void>;
|
|
21
|
+
readonly stdoutIsTerminal: boolean;
|
|
22
|
+
/** Raw bytes to stdout, such as a downloaded file. */
|
|
23
|
+
readonly writeBytes: (chunk: Uint8Array) => Promise<void>;
|
|
24
|
+
readonly writeError: (text: string) => void;
|
|
25
|
+
readonly writeOutput: (text: string) => void;
|
|
26
|
+
}
|
|
27
|
+
export interface ProcessResult {
|
|
28
|
+
readonly exitCode: number;
|
|
29
|
+
/** Its stdout and stderr together, as a person would have seen them. */
|
|
30
|
+
readonly output: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function nodeCloudRuntime(signal: AbortSignal): CloudRuntime;
|
|
33
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/cli/cloud/runtime.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IACzB,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IACnE,QAAQ,CAAC,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACxC,2EAA2E;IAC3E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IAC9F,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,iGAAiG;IACjG,QAAQ,CAAC,UAAU,EAAE,CACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,KAChC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,sDAAsD;IACtD,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AAED,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,YAAY,CA2BlE"}
|