dexto 2.0.0-beta.0 → 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.
Files changed (102) hide show
  1. package/dist/agents/coding-agent/coding-agent.yml +0 -2
  2. package/dist/cli/agent-audit.d.ts +12 -0
  3. package/dist/cli/agent-audit.d.ts.map +1 -0
  4. package/dist/cli/agent-audit.js +52 -0
  5. package/dist/cli/cloud/command.d.ts +3 -39
  6. package/dist/cli/cloud/command.d.ts.map +1 -1
  7. package/dist/cli/cloud/command.js +12 -60
  8. package/dist/cli/cloud/commands/account.d.ts.map +1 -1
  9. package/dist/cli/cloud/commands/account.js +2 -1
  10. package/dist/cli/cloud/commands/agents.d.ts.map +1 -1
  11. package/dist/cli/cloud/commands/agents.js +3 -1
  12. package/dist/cli/cloud/commands/artifacts.d.ts +3 -0
  13. package/dist/cli/cloud/commands/artifacts.d.ts.map +1 -0
  14. package/dist/cli/cloud/commands/artifacts.js +267 -0
  15. package/dist/cli/cloud/commands/automations.d.ts.map +1 -1
  16. package/dist/cli/cloud/commands/automations.js +2 -1
  17. package/dist/cli/cloud/commands/chats.d.ts.map +1 -1
  18. package/dist/cli/cloud/commands/chats.js +20 -5
  19. package/dist/cli/cloud/commands/data-deletions.d.ts.map +1 -1
  20. package/dist/cli/cloud/commands/data-deletions.js +2 -1
  21. package/dist/cli/cloud/commands/deploys.d.ts.map +1 -1
  22. package/dist/cli/cloud/commands/deploys.js +3 -1
  23. package/dist/cli/cloud/commands/drive.d.ts.map +1 -1
  24. package/dist/cli/cloud/commands/drive.js +2 -1
  25. package/dist/cli/cloud/commands/files.d.ts.map +1 -1
  26. package/dist/cli/cloud/commands/files.js +3 -1
  27. package/dist/cli/cloud/commands/models.d.ts.map +1 -1
  28. package/dist/cli/cloud/commands/models.js +3 -1
  29. package/dist/cli/cloud/commands/profile.d.ts.map +1 -1
  30. package/dist/cli/cloud/commands/profile.js +2 -1
  31. package/dist/cli/cloud/commands/publish.d.ts.map +1 -1
  32. package/dist/cli/cloud/commands/publish.js +2 -1
  33. package/dist/cli/cloud/commands/sandboxes.d.ts.map +1 -1
  34. package/dist/cli/cloud/commands/sandboxes.js +2 -1
  35. package/dist/cli/cloud/commands/secrets.d.ts.map +1 -1
  36. package/dist/cli/cloud/commands/secrets.js +2 -1
  37. package/dist/cli/cloud/commands/skills.d.ts.map +1 -1
  38. package/dist/cli/cloud/commands/skills.js +2 -1
  39. package/dist/cli/cloud/commands/traces.d.ts +3 -0
  40. package/dist/cli/cloud/commands/traces.d.ts.map +1 -0
  41. package/dist/cli/cloud/commands/traces.js +142 -0
  42. package/dist/cli/cloud/commands/workspace-apps.d.ts.map +1 -1
  43. package/dist/cli/cloud/commands/workspace-apps.js +2 -1
  44. package/dist/cli/cloud/commands/workspace.d.ts.map +1 -1
  45. package/dist/cli/cloud/commands/workspace.js +3 -1
  46. package/dist/cli/cloud/host.d.ts.map +1 -1
  47. package/dist/cli/cloud/host.js +4 -0
  48. package/dist/cli/cloud/output.d.ts.map +1 -1
  49. package/dist/cli/cloud/output.js +2 -1
  50. package/dist/cli/cloud/run.d.ts.map +1 -1
  51. package/dist/cli/cloud/run.js +10 -10
  52. package/dist/cli/cloud/transfer.d.ts.map +1 -1
  53. package/dist/cli/cloud/transfer.js +2 -1
  54. package/dist/cli/cloud/v1.d.ts +2 -1
  55. package/dist/cli/cloud/v1.d.ts.map +1 -1
  56. package/dist/cli/cloud/v1.js +2 -1
  57. package/dist/cli/commands/auth/sign-in-commands.d.ts.map +1 -1
  58. package/dist/cli/commands/auth/sign-in-commands.js +2 -1
  59. package/dist/cli/commands/cloud/register.d.ts.map +1 -1
  60. package/dist/cli/commands/cloud/register.js +2 -0
  61. package/dist/cli/commands/run/headless.d.ts.map +1 -1
  62. package/dist/cli/commands/run/headless.js +55 -0
  63. package/dist/cli/commands/run/step-log.d.ts +11 -0
  64. package/dist/cli/commands/run/step-log.d.ts.map +1 -0
  65. package/dist/cli/commands/run/step-log.js +42 -0
  66. package/dist/cli/failure.d.ts +29 -0
  67. package/dist/cli/failure.d.ts.map +1 -0
  68. package/dist/cli/failure.js +31 -0
  69. package/dist/cli/help-json.d.ts.map +1 -1
  70. package/dist/cli/help-json.js +1 -1
  71. package/dist/cli/import/claude-code.d.ts +10 -0
  72. package/dist/cli/import/claude-code.d.ts.map +1 -0
  73. package/dist/cli/import/claude-code.js +131 -0
  74. package/dist/cli/import/codex.d.ts +27 -0
  75. package/dist/cli/import/codex.d.ts.map +1 -0
  76. package/dist/cli/import/codex.js +148 -0
  77. package/dist/cli/import/git.d.ts +19 -0
  78. package/dist/cli/import/git.d.ts.map +1 -0
  79. package/dist/cli/import/git.js +95 -0
  80. package/dist/cli/import/local-chats.d.ts +28 -0
  81. package/dist/cli/import/local-chats.d.ts.map +1 -0
  82. package/dist/cli/import/local-chats.js +129 -0
  83. package/dist/cli/import/redaction.d.ts +37 -0
  84. package/dist/cli/import/redaction.d.ts.map +1 -0
  85. package/dist/cli/import/redaction.js +148 -0
  86. package/dist/cli/import/test-utils.d.ts +16 -0
  87. package/dist/cli/import/test-utils.d.ts.map +1 -0
  88. package/dist/cli/import/test-utils.js +223 -0
  89. package/dist/cli/import/transcript.d.ts +75 -0
  90. package/dist/cli/import/transcript.d.ts.map +1 -0
  91. package/dist/cli/import/transcript.js +123 -0
  92. package/dist/cli/interaction.d.ts +18 -0
  93. package/dist/cli/interaction.d.ts.map +1 -0
  94. package/dist/cli/interaction.js +30 -0
  95. package/dist/cli/output.d.ts +9 -0
  96. package/dist/cli/output.d.ts.map +1 -0
  97. package/dist/cli/output.js +6 -0
  98. package/dist/index-main.js +12 -1
  99. package/package.json +10 -10
  100. package/dist/cli/cloud/local-chats.d.ts +0 -73
  101. package/dist/cli/cloud/local-chats.d.ts.map +0 -1
  102. package/dist/cli/cloud/local-chats.js +0 -441
@@ -127,8 +127,6 @@ permissions:
127
127
  - plan_create # Create plan without approval
128
128
  - plan_read # Read plan without approval
129
129
  - plan_update # Update plan without approval
130
- - wait_for # Wait for background tasks without approval
131
- - check_task # Check background tasks without approval
132
130
 
133
131
  # Compaction configuration - automatically summarizes conversation when context is full
134
132
  compaction:
@@ -0,0 +1,12 @@
1
+ import type { Command } from 'commander';
2
+ export interface AuditRow {
3
+ command: string;
4
+ json: boolean;
5
+ dryRun: boolean;
6
+ nonInteractiveFlag: boolean;
7
+ examples: boolean;
8
+ }
9
+ export declare function auditCommander(program: Command): AuditRow[];
10
+ export declare function auditCloud(commands: readonly import('./cloud/command.js').Command[]): AuditRow[];
11
+ export declare function auditProgram(program: Command, commands: readonly import('./cloud/command.js').Command[]): AuditRow[];
12
+ //# sourceMappingURL=agent-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-audit.d.ts","sourceRoot":"","sources":["../../src/cli/agent-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,WAAW,QAAQ;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,EAAE,CAiC3D;AAGD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,SAAS,OAAO,oBAAoB,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAQhG;AAED,wBAAgB,YAAY,CACxB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,SAAS,OAAO,oBAAoB,EAAE,OAAO,EAAE,GAC1D,QAAQ,EAAE,CAUZ"}
@@ -0,0 +1,52 @@
1
+ export function auditCommander(program) {
2
+ const rows = [];
3
+ function visit(command, path) {
4
+ const words = [...path, command.name()];
5
+ if (typeof Reflect.get(command, '_actionHandler') === 'function') {
6
+ const options = command.options.map((option) => option.long);
7
+ let help = '';
8
+ const output = { ...command.configureOutput() };
9
+ command.configureOutput({
10
+ writeOut: (text) => {
11
+ help += text;
12
+ },
13
+ });
14
+ try {
15
+ command.outputHelp();
16
+ }
17
+ finally {
18
+ command.configureOutput(output);
19
+ }
20
+ rows.push({
21
+ command: words.join(' '),
22
+ json: options.includes('--json'),
23
+ dryRun: options.includes('--dry-run'),
24
+ nonInteractiveFlag: options.includes('--no-interactive') ||
25
+ options.includes('--non-interactive') ||
26
+ options.includes('--yes'),
27
+ examples: /^\s*examples:\s*$/imu.test(help),
28
+ });
29
+ }
30
+ for (const child of command.commands)
31
+ visit(child, words);
32
+ }
33
+ for (const command of program.commands)
34
+ visit(command, []);
35
+ return rows;
36
+ }
37
+ // JSON is an engine-wide option; cloud help currently has no examples. These are not per-command behavioral checks.
38
+ export function auditCloud(commands) {
39
+ return commands.map((command) => ({
40
+ command: command.path.join(' '),
41
+ json: true,
42
+ dryRun: 'dry-run' in (command.options ?? {}),
43
+ nonInteractiveFlag: 'yes' in (command.options ?? {}),
44
+ examples: false,
45
+ }));
46
+ }
47
+ export function auditProgram(program, commands) {
48
+ const cloud = auditCloud(commands);
49
+ const cloudNames = cloud.map((row) => row.command);
50
+ const local = auditCommander(program).filter((row) => !cloudNames.some((name) => name === row.command || name.startsWith(`${row.command} `)));
51
+ return [...local, ...cloud].sort((a, b) => a.command < b.command ? -1 : a.command > b.command ? 1 : 0);
52
+ }
@@ -1,4 +1,5 @@
1
1
  import type { CloudClient } from '@dexto/cloud-client';
2
+ import { CommandFailure } from '../failure.js';
2
3
  import type { Connection, ConnectionOverrides } from './connection.js';
3
4
  import type { Output } from './output.js';
4
5
  import type { CloudRuntime } from './runtime.js';
@@ -37,34 +38,6 @@ export interface CommandContext {
37
38
  export declare class UsageError extends Error {
38
39
  constructor(message: string);
39
40
  }
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
41
  /** A permission the sign-in lacks: signing in again for `scope` (one, or several comma-separated) fixes it. */
69
42
  export declare class MissingScopeFailure extends CommandFailure {
70
43
  readonly scope: string;
@@ -75,6 +48,8 @@ export declare function requiredOption(input: CommandInput, name: string): strin
75
48
  export declare function listOption(input: CommandInput, name: string): string[];
76
49
  export declare function flag(input: CommandInput, name: string): boolean;
77
50
  export declare function integerOption(input: CommandInput, name: string): number | undefined;
51
+ /** A string option that must be one of `values`, checked before anything is sent. */
52
+ export declare function choiceOption<const T extends string>(input: CommandInput, name: string, values: readonly T[]): T | undefined;
78
53
  export declare function argument(input: CommandInput, index: number, name: string): string;
79
54
  /** `--limit` and `--after`, which every list takes. */
80
55
  export declare const PAGE_OPTIONS: {
@@ -111,21 +86,12 @@ export declare function readJsonBody(context: CommandContext, input: CommandInpu
111
86
  export declare function isJsonObject(value: unknown): value is Record<string, unknown>;
112
87
  /** A value the person types, hidden when secret, or piped on stdin. */
113
88
  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
89
  export declare const YES_OPTION: {
117
90
  readonly yes: {
118
91
  readonly description: "Go ahead without being asked. Pass it only once your person has agreed.";
119
92
  readonly type: "boolean";
120
93
  };
121
94
  };
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
95
  /**
130
96
  * Whether a sign-in here should use a device code: no one is at this terminal, or it is an SSH
131
97
  * session, whose loopback redirect a browser on the person's own device can't reach.
@@ -138,6 +104,4 @@ export type SignInContext = Pick<CommandContext, 'overrides' | 'runtime'>;
138
104
  * finish it.
139
105
  */
140
106
  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
107
  //# sourceMappingURL=command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/cli/cloud/command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/cli/cloud/command.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  // The shape every cloud command shares: its path, arguments, options and handler.
2
2
  import { readFile } from 'node:fs/promises';
3
+ import { CommandFailure } from '../failure.js';
4
+ import { shellWord } from '../interaction.js';
3
5
  /** A mistake in how the command was called: printed with the command's usage. */
4
6
  export class UsageError extends Error {
5
7
  constructor(message) {
@@ -7,37 +9,6 @@ export class UsageError extends Error {
7
9
  this.name = 'UsageError';
8
10
  }
9
11
  }
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
12
  /** A permission the sign-in lacks: signing in again for `scope` (one, or several comma-separated) fixes it. */
42
13
  export class MissingScopeFailure extends CommandFailure {
43
14
  scope;
@@ -75,6 +46,16 @@ export function integerOption(input, name) {
75
46
  throw new UsageError(`--${name} must be a whole number.`);
76
47
  return parsed;
77
48
  }
49
+ /** A string option that must be one of `values`, checked before anything is sent. */
50
+ export function choiceOption(input, name, values) {
51
+ const value = stringOption(input, name);
52
+ if (value === undefined)
53
+ return undefined;
54
+ const found = values.find((each) => each === value);
55
+ if (found === undefined)
56
+ throw new UsageError(`--${name} must be one of: ${values.join(', ')}.`);
57
+ return found;
58
+ }
78
59
  export function argument(input, index, name) {
79
60
  const value = input.positionals[index];
80
61
  if (value === undefined)
@@ -140,37 +121,12 @@ export async function readValue(context, question, secret) {
140
121
  throw new UsageError('No value was given.');
141
122
  return value;
142
123
  }
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
124
  export const YES_OPTION = {
151
125
  yes: {
152
126
  description: 'Go ahead without being asked. Pass it only once your person has agreed.',
153
127
  type: 'boolean',
154
128
  },
155
129
  };
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
130
  /**
175
131
  * Whether a sign-in here should use a device code: no one is at this terminal, or it is an SSH
176
132
  * session, whose loopback redirect a browser on the person's own device can't reach.
@@ -196,7 +152,3 @@ export function signInCommand(context, scope) {
196
152
  .map(shellWord)
197
153
  .join(' ');
198
154
  }
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
- }
@@ -1 +1 @@
1
- {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/account.ts"],"names":[],"mappings":"AAIA,OAAO,EAOH,KAAK,OAAO,EAEf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAE7E,uFAAuF;AACvF,MAAM,MAAM,SAAS,GAAG,CAAC,EAAE,EAAE;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAChC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAW7B,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,OAAO,EAAE,CAoJzF"}
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/account.ts"],"names":[],"mappings":"AAMA,OAAO,EAMH,KAAK,OAAO,EAEf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAE7E,uFAAuF;AACvF,MAAM,MAAM,SAAS,GAAG,CAAC,EAAE,EAAE;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAChC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAW7B,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,OAAO,EAAE,CAoJzF"}
@@ -1,7 +1,8 @@
1
1
  // `login`, `logout`, `whoami`, `accounts`, `models list` and `billing`: who commands act as, and
2
2
  // the models and credits that sign-in reaches, under the CLI's one output contract.
3
+ import { confirm } from '../../interaction.js';
3
4
  import { unwrap } from '@dexto/cloud-client';
4
- import { argument, confirm, flag, listOption, stringOption, YES_OPTION, } from '../command.js';
5
+ import { argument, flag, listOption, stringOption, YES_OPTION, } from '../command.js';
5
6
  function signInIo(context) {
6
7
  return {
7
8
  result: (value, text) => context.output.result(value, text),
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/agents.ts"],"names":[],"mappings":"AAKA,OAAO,EAgBH,KAAK,OAAO,EAIf,MAAM,eAAe,CAAC;AA8oBvB,eAAO,MAAM,aAAa,EAAE,SAAS,OAAO,EAiB3C,CAAC"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/agents.ts"],"names":[],"mappings":"AAQA,OAAO,EAaH,KAAK,OAAO,EAIf,MAAM,eAAe,CAAC;AA8oBvB,eAAO,MAAM,aAAa,EAAE,SAAS,OAAO,EAiB3C,CAAC"}
@@ -1,7 +1,9 @@
1
1
  // `cloud agents`: define agents, chat with them, and read their sessions, messages and runs.
2
+ import { EXIT_CODES } from '../../failure.js';
3
+ import { confirm, requireConsent } from '../../interaction.js';
2
4
  import chalk from 'chalk';
3
5
  import { unwrap } from '@dexto/cloud-client';
4
- import { argument, BODY_OPTIONS, confirm, EXIT_CODES, flag, integerOption, isJsonObject, listOption, PAGE_OPTIONS, pageQuery, readJsonBody, requireConsent, stringOption, UsageError, YES_OPTION, } from '../command.js';
6
+ import { argument, BODY_OPTIONS, flag, integerOption, isJsonObject, listOption, PAGE_OPTIONS, pageQuery, readJsonBody, stringOption, UsageError, YES_OPTION, } from '../command.js';
5
7
  import { sessionEvents } from '../events.js';
6
8
  function agentPath(agentId) {
7
9
  return { params: { path: { agent_id: agentId } } };
@@ -0,0 +1,3 @@
1
+ import { type Command } from '../command.js';
2
+ export declare const artifactCommands: readonly Command[];
3
+ //# sourceMappingURL=artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/artifacts.ts"],"names":[],"mappings":"AASA,OAAO,EAWH,KAAK,OAAO,EAIf,MAAM,eAAe,CAAC;AAyUvB,eAAO,MAAM,gBAAgB,EAAE,SAAS,OAAO,EAAwC,CAAC"}
@@ -0,0 +1,267 @@
1
+ // `workspace artifacts`: the person's saved HTML Artifacts, over Dexto's typed Artifacts tools.
2
+ import { CommandFailure } from '../../failure.js';
3
+ import { readFile, writeFile } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { z } from 'zod';
6
+ import { argument, choiceOption, flag, integerOption, listOption, PAGE_OPTIONS, requiredOption, stringOption, UsageError, YES_OPTION, } from '../command.js';
7
+ import { requireLoginScopes } from './deploys.js';
8
+ import { agreeToCall, listWorkspaceTools, queryWorkspaceTool, toolCallLevel } from './workspace.js';
9
+ /** What Dexto keeps of one Artifact's HTML. */
10
+ const MAX_HTML_BYTES = 524_288;
11
+ const KINDS = [
12
+ 'document',
13
+ 'plan',
14
+ 'mockup',
15
+ 'prototype',
16
+ 'slide-deck',
17
+ 'visualization',
18
+ 'interactive',
19
+ 'other',
20
+ ];
21
+ const SURFACES = ['inline', 'panel', 'fullscreen'];
22
+ const RENDERERS = ['html', 'reveal'];
23
+ const VISIBILITIES = ['private', 'org-shared', 'link-shared'];
24
+ const SummarySchema = z.object({
25
+ artifactId: z.string(),
26
+ kind: z.string(),
27
+ preferredSurface: z.string(),
28
+ summary: z.string(),
29
+ title: z.string(),
30
+ updatedAt: z.string(),
31
+ });
32
+ const ListSchema = z.object({ artifacts: z.array(SummarySchema), next: z.string().nullable() });
33
+ const ArtifactSchema = SummarySchema.extend({
34
+ html: z.string(),
35
+ renderer: z.string().nullable(),
36
+ });
37
+ const GetSchema = z.object({ artifact: ArtifactSchema.nullable() });
38
+ const SavedSchema = z.object({
39
+ artifact: z.object({ artifactId: z.string(), title: z.string() }),
40
+ });
41
+ const SharedSchema = z.object({ url: z.string().nullable(), visibility: z.string() });
42
+ const COLUMNS = [
43
+ { header: 'id', value: (artifact) => artifact.artifactId },
44
+ { header: 'title', value: (artifact) => artifact.title },
45
+ { header: 'kind', value: (artifact) => artifact.kind },
46
+ { header: 'updated', value: (artifact) => artifact.updatedAt },
47
+ ];
48
+ const CONTENT_OPTIONS = {
49
+ kind: { description: `What it is: ${KINDS.join(', ')}.`, type: 'string' },
50
+ renderer: {
51
+ description: 'html, or reveal for a slide-deck written for reveal.js.',
52
+ type: 'string',
53
+ },
54
+ summary: { description: 'One or two lines on what it is.', type: 'string' },
55
+ surface: {
56
+ description: `Where it opens: ${SURFACES.join(', ')}.`,
57
+ type: 'string',
58
+ },
59
+ tag: { description: 'A tag; repeat for more.', multiple: true, type: 'string' },
60
+ title: { description: "The Artifact's title.", type: 'string' },
61
+ };
62
+ const DRY_RUN_OPTION = {
63
+ 'dry-run': {
64
+ description: 'Check the input and show the call, without making it.',
65
+ type: 'boolean',
66
+ },
67
+ };
68
+ const list = {
69
+ options: PAGE_OPTIONS,
70
+ path: ['workspace', 'artifacts', 'list'],
71
+ summary: 'List your saved Artifacts, newest first.',
72
+ async run(context, input) {
73
+ await requireLoginScopes(context, ['apps:read']);
74
+ const after = stringOption(input, 'after');
75
+ const limit = integerOption(input, 'limit');
76
+ const page = ListSchema.parse(await queryWorkspaceTool(context, 'dexto_artifacts_list', {
77
+ ...(after === undefined ? {} : { cursor: after }),
78
+ ...(limit === undefined ? {} : { limit }),
79
+ }));
80
+ context.output.list({ data: page.artifacts, has_more: page.next !== null, next_after: page.next }, COLUMNS);
81
+ },
82
+ };
83
+ const get = {
84
+ arguments: '<artifact_id>',
85
+ options: {
86
+ out: {
87
+ description: 'Write the HTML to this file, and show the rest without it.',
88
+ type: 'string',
89
+ valueName: 'PATH',
90
+ },
91
+ },
92
+ path: ['workspace', 'artifacts', 'get'],
93
+ summary: 'Show one Artifact, with its HTML or with --out writing the HTML to a file.',
94
+ async run(context, input) {
95
+ await requireLoginScopes(context, ['apps:read']);
96
+ const artifact = await readArtifact(context, argument(input, 0, 'artifact_id'));
97
+ const out = stringOption(input, 'out');
98
+ if (out === undefined)
99
+ return context.output.record(artifact);
100
+ await writeFile(out, artifact.html, 'utf8');
101
+ const { html: _html, ...rest } = artifact;
102
+ context.output.record({ ...rest, htmlPath: path.resolve(out) });
103
+ },
104
+ };
105
+ const create = {
106
+ arguments: '<file>',
107
+ options: {
108
+ ...CONTENT_OPTIONS,
109
+ collection: {
110
+ description: 'A collection to put it in, by id; repeat for more.',
111
+ multiple: true,
112
+ type: 'string',
113
+ },
114
+ 'idempotency-key': {
115
+ description: 'Any string unique to this Artifact: running again with the same key returns the first one instead of a copy.',
116
+ type: 'string',
117
+ valueName: 'KEY',
118
+ },
119
+ ...DRY_RUN_OPTION,
120
+ ...YES_OPTION,
121
+ },
122
+ path: ['workspace', 'artifacts', 'create'],
123
+ summary: "Save an HTML file (or - for stdin) as an Artifact in your library. Its title defaults to the file's name.",
124
+ async run(context, input) {
125
+ await requireLoginScopes(context, ['apps:execute']);
126
+ const file = argument(input, 0, 'file');
127
+ const title = stringOption(input, 'title') ??
128
+ (file === '-' ? requiredOption(input, 'title') : path.parse(file).name);
129
+ const key = stringOption(input, 'idempotency-key');
130
+ const collections = listOption(input, 'collection');
131
+ const call = {
132
+ ...contentFields(input, {
133
+ kind: 'document',
134
+ preferredSurface: 'panel',
135
+ renderer: 'html',
136
+ summary: '',
137
+ title,
138
+ }),
139
+ html: await readHtml(context, file),
140
+ ...(collections.length === 0 ? {} : { collectionIds: collections }),
141
+ ...(key === undefined ? {} : { idempotencyKey: key }),
142
+ };
143
+ const saved = await save(context, input, 'dexto_artifacts_create', call, `Save ${title}`);
144
+ if (saved === null)
145
+ return;
146
+ context.output.result(saved.value, `Saved ${saved.artifact.title} as Artifact ${saved.artifact.artifactId}.`);
147
+ },
148
+ };
149
+ const replace = {
150
+ arguments: '<artifact_id> <file>',
151
+ options: { ...CONTENT_OPTIONS, ...DRY_RUN_OPTION, ...YES_OPTION },
152
+ path: ['workspace', 'artifacts', 'replace'],
153
+ summary: 'Replace an Artifact with an HTML file (or - for stdin), keeping its id; it keeps its title, kind, summary, surface and renderer unless you give new ones.',
154
+ async run(context, input) {
155
+ await requireLoginScopes(context, ['apps:read', 'apps:execute']);
156
+ const artifactId = argument(input, 0, 'artifact_id');
157
+ const html = await readHtml(context, argument(input, 1, 'file'));
158
+ const current = await readArtifact(context, artifactId);
159
+ const call = {
160
+ artifactId,
161
+ ...contentFields(input, {
162
+ kind: current.kind,
163
+ preferredSurface: current.preferredSurface,
164
+ renderer: current.renderer ?? 'html',
165
+ summary: current.summary,
166
+ title: current.title,
167
+ }),
168
+ html,
169
+ };
170
+ const saved = await save(context, input, 'dexto_artifacts_replace', call, `Replace Artifact ${artifactId}`);
171
+ if (saved === null)
172
+ return;
173
+ context.output.result(saved.value, `Replaced Artifact ${artifactId}.`);
174
+ },
175
+ };
176
+ const share = {
177
+ arguments: '<artifact_id>',
178
+ options: {
179
+ visibility: {
180
+ description: 'private (only you), org-shared (your organization) or link-shared (anyone with the link).',
181
+ type: 'string',
182
+ },
183
+ ...DRY_RUN_OPTION,
184
+ ...YES_OPTION,
185
+ },
186
+ path: ['workspace', 'artifacts', 'share'],
187
+ summary: 'Change who can open an Artifact: only you, your organization, or anyone with its link.',
188
+ async run(context, input) {
189
+ await requireLoginScopes(context, ['apps:execute']);
190
+ const visibility = choiceOption(input, 'visibility', VISIBILITIES);
191
+ if (visibility === undefined)
192
+ throw new UsageError('--visibility is required.');
193
+ const artifactId = argument(input, 0, 'artifact_id');
194
+ const call = { artifactId, visibility };
195
+ const tool = await requireTool(context, 'dexto_artifacts_share');
196
+ if (flag(input, 'dry-run'))
197
+ return dryRun(context, 'dexto_artifacts_share', call);
198
+ const agreed = await agreeToCall(context, {
199
+ level: toolCallLevel(tool, call),
200
+ schema: tool.inputSchema,
201
+ title: `Make Artifact ${artifactId} ${visibility}`,
202
+ }, flag(input, 'yes'));
203
+ const value = await queryWorkspaceTool(context, 'dexto_artifacts_share', {
204
+ ...call,
205
+ ...agreed,
206
+ });
207
+ const shared = SharedSchema.parse(value);
208
+ context.output.result(value, shared.url === null
209
+ ? `Artifact ${artifactId} is now ${shared.visibility}.`
210
+ : `Artifact ${artifactId} is now ${shared.visibility}: ${shared.url}`);
211
+ },
212
+ };
213
+ async function readArtifact(context, artifactId) {
214
+ const { artifact } = GetSchema.parse(await queryWorkspaceTool(context, 'dexto_artifacts_get', { artifactId }));
215
+ if (artifact === null)
216
+ throw new CommandFailure('not_found', `There is no Artifact ${artifactId}.`, null);
217
+ return artifact;
218
+ }
219
+ /** The HTML of a file, or of stdin for -, checked against what an Artifact holds. */
220
+ async function readHtml(context, file) {
221
+ const html = file === '-' ? await context.runtime.readStdin() : await readFile(file, 'utf8');
222
+ if (html.length === 0)
223
+ throw new UsageError(`${file === '-' ? 'stdin' : file} is empty.`);
224
+ const bytes = Buffer.byteLength(html, 'utf8');
225
+ if (bytes > MAX_HTML_BYTES)
226
+ throw new UsageError(`The HTML is ${bytes} bytes; an Artifact holds up to ${MAX_HTML_BYTES}.`);
227
+ return html;
228
+ }
229
+ /** The content flags given, each falling back to `defaults`. */
230
+ function contentFields(input, defaults) {
231
+ const tags = listOption(input, 'tag');
232
+ const fields = {
233
+ kind: choiceOption(input, 'kind', KINDS) ?? defaults.kind,
234
+ preferredSurface: choiceOption(input, 'surface', SURFACES) ?? defaults.preferredSurface,
235
+ renderer: choiceOption(input, 'renderer', RENDERERS) ?? defaults.renderer,
236
+ summary: stringOption(input, 'summary') ?? defaults.summary,
237
+ title: stringOption(input, 'title') ?? defaults.title,
238
+ ...(tags.length === 0 ? {} : { tags }),
239
+ };
240
+ if (fields.renderer === 'reveal' && fields.kind !== 'slide-deck')
241
+ throw new UsageError('--renderer reveal needs --kind slide-deck.');
242
+ return fields;
243
+ }
244
+ async function requireTool(context, name) {
245
+ const tool = (await listWorkspaceTools(context)).find((each) => each.name === name);
246
+ if (tool === undefined)
247
+ throw new CommandFailure('failed', "This Dexto can't manage Artifacts yet.", null);
248
+ return tool;
249
+ }
250
+ /** Creates or replaces once agreed, or with --dry-run shows the call; null when it only showed it. */
251
+ async function save(context, input, name, call, title) {
252
+ const tool = await requireTool(context, name);
253
+ if (flag(input, 'dry-run')) {
254
+ dryRun(context, name, call);
255
+ return null;
256
+ }
257
+ const agreed = await agreeToCall(context, { level: toolCallLevel(tool, call), schema: tool.inputSchema, title }, flag(input, 'yes'));
258
+ const value = await queryWorkspaceTool(context, name, { ...call, ...agreed });
259
+ return { artifact: SavedSchema.parse(value).artifact, value };
260
+ }
261
+ /** The call a write would make, its HTML shown by size. */
262
+ function dryRun(context, tool, call) {
263
+ const { html, ...rest } = call;
264
+ const shown = typeof html === 'string' ? { ...rest, htmlBytes: Buffer.byteLength(html, 'utf8') } : rest;
265
+ context.output.result({ dryRun: true, tool, arguments: shown }, `Would call ${tool} with ${JSON.stringify(shown)}.`);
266
+ }
267
+ export const artifactCommands = [list, get, create, replace, share];
@@ -1 +1 @@
1
- {"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/automations.ts"],"names":[],"mappings":"AAIA,OAAO,EAYH,KAAK,OAAO,EAEf,MAAM,eAAe,CAAC;AAoSvB,eAAO,MAAM,kBAAkB,EAAE,SAAS,OAAO,EAWhD,CAAC"}
1
+ {"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/automations.ts"],"names":[],"mappings":"AAMA,OAAO,EAWH,KAAK,OAAO,EAEf,MAAM,eAAe,CAAC;AAoSvB,eAAO,MAAM,kBAAkB,EAAE,SAAS,OAAO,EAWhD,CAAC"}
@@ -1,6 +1,7 @@
1
1
  // `cloud automations`: run the project's agents on a schedule or on a signed webhook.
2
+ import { requireConsent } from '../../interaction.js';
2
3
  import { unwrap } from '@dexto/cloud-client';
3
- import { argument, BODY_OPTIONS, PAGE_OPTIONS, pageQuery, readJsonBody, requireConsent, stringOption, UsageError, YES_OPTION, flag, isJsonObject, } from '../command.js';
4
+ import { argument, BODY_OPTIONS, PAGE_OPTIONS, pageQuery, readJsonBody, stringOption, UsageError, YES_OPTION, flag, isJsonObject, } from '../command.js';
4
5
  function automationPath(id) {
5
6
  return { params: { path: { automation_id: id } } };
6
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"chats.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/chats.ts"],"names":[],"mappings":"AAIA,OAAO,EAOH,KAAK,OAAO,EAIf,MAAM,eAAe,CAAC;AAwPvB,eAAO,MAAM,YAAY,EAAE,SAAS,OAAO,EAAyB,CAAC"}
1
+ {"version":3,"file":"chats.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/chats.ts"],"names":[],"mappings":"AAMA,OAAO,EAMH,KAAK,OAAO,EAIf,MAAM,eAAe,CAAC;AAwQvB,eAAO,MAAM,YAAY,EAAE,SAAS,OAAO,EAAyB,CAAC"}