@agentuity/cli 0.0.105 → 0.0.106

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 (204) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +93 -21
  3. package/dist/cli.js.map +1 -1
  4. package/dist/cmd/build/ast.d.ts.map +1 -1
  5. package/dist/cmd/build/ast.js +130 -4
  6. package/dist/cmd/build/ast.js.map +1 -1
  7. package/dist/cmd/build/entry-generator.d.ts.map +1 -1
  8. package/dist/cmd/build/entry-generator.js +8 -2
  9. package/dist/cmd/build/entry-generator.js.map +1 -1
  10. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
  11. package/dist/cmd/build/vite/registry-generator.js +8 -9
  12. package/dist/cmd/build/vite/registry-generator.js.map +1 -1
  13. package/dist/cmd/cloud/db/create.d.ts.map +1 -1
  14. package/dist/cmd/cloud/db/create.js +11 -2
  15. package/dist/cmd/cloud/db/create.js.map +1 -1
  16. package/dist/cmd/cloud/db/delete.d.ts.map +1 -1
  17. package/dist/cmd/cloud/db/delete.js +13 -2
  18. package/dist/cmd/cloud/db/delete.js.map +1 -1
  19. package/dist/cmd/cloud/deploy.js +3 -3
  20. package/dist/cmd/cloud/deploy.js.map +1 -1
  21. package/dist/cmd/cloud/env/delete.js +1 -1
  22. package/dist/cmd/cloud/env/delete.js.map +1 -1
  23. package/dist/cmd/cloud/env/import.js +4 -4
  24. package/dist/cmd/cloud/env/import.js.map +1 -1
  25. package/dist/cmd/cloud/env/pull.d.ts.map +1 -1
  26. package/dist/cmd/cloud/env/pull.js +7 -9
  27. package/dist/cmd/cloud/env/pull.js.map +1 -1
  28. package/dist/cmd/cloud/env/push.js +2 -2
  29. package/dist/cmd/cloud/env/push.js.map +1 -1
  30. package/dist/cmd/cloud/env/set.js +3 -3
  31. package/dist/cmd/cloud/env/set.js.map +1 -1
  32. package/dist/cmd/cloud/index.d.ts.map +1 -1
  33. package/dist/cmd/cloud/index.js +2 -0
  34. package/dist/cmd/cloud/index.js.map +1 -1
  35. package/dist/cmd/cloud/sandbox/cp.d.ts +3 -0
  36. package/dist/cmd/cloud/sandbox/cp.d.ts.map +1 -0
  37. package/dist/cmd/cloud/sandbox/cp.js +334 -0
  38. package/dist/cmd/cloud/sandbox/cp.js.map +1 -0
  39. package/dist/cmd/cloud/sandbox/create.d.ts +3 -0
  40. package/dist/cmd/cloud/sandbox/create.d.ts.map +1 -0
  41. package/dist/cmd/cloud/sandbox/create.js +105 -0
  42. package/dist/cmd/cloud/sandbox/create.js.map +1 -0
  43. package/dist/cmd/cloud/sandbox/delete.d.ts +3 -0
  44. package/dist/cmd/cloud/sandbox/delete.d.ts.map +1 -0
  45. package/dist/cmd/cloud/sandbox/delete.js +72 -0
  46. package/dist/cmd/cloud/sandbox/delete.js.map +1 -0
  47. package/dist/cmd/cloud/sandbox/exec.d.ts +3 -0
  48. package/dist/cmd/cloud/sandbox/exec.d.ts.map +1 -0
  49. package/dist/cmd/cloud/sandbox/exec.js +211 -0
  50. package/dist/cmd/cloud/sandbox/exec.js.map +1 -0
  51. package/dist/cmd/cloud/sandbox/execution/get.d.ts +3 -0
  52. package/dist/cmd/cloud/sandbox/execution/get.d.ts.map +1 -0
  53. package/dist/cmd/cloud/sandbox/execution/get.js +96 -0
  54. package/dist/cmd/cloud/sandbox/execution/get.js.map +1 -0
  55. package/dist/cmd/cloud/sandbox/execution/index.d.ts +3 -0
  56. package/dist/cmd/cloud/sandbox/execution/index.d.ts.map +1 -0
  57. package/dist/cmd/cloud/sandbox/execution/index.js +24 -0
  58. package/dist/cmd/cloud/sandbox/execution/index.js.map +1 -0
  59. package/dist/cmd/cloud/sandbox/execution/list.d.ts +3 -0
  60. package/dist/cmd/cloud/sandbox/execution/list.d.ts.map +1 -0
  61. package/dist/cmd/cloud/sandbox/execution/list.js +100 -0
  62. package/dist/cmd/cloud/sandbox/execution/list.js.map +1 -0
  63. package/dist/cmd/cloud/sandbox/get.d.ts +3 -0
  64. package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -0
  65. package/dist/cmd/cloud/sandbox/get.js +95 -0
  66. package/dist/cmd/cloud/sandbox/get.js.map +1 -0
  67. package/dist/cmd/cloud/sandbox/index.d.ts +3 -0
  68. package/dist/cmd/cloud/sandbox/index.d.ts.map +1 -0
  69. package/dist/cmd/cloud/sandbox/index.js +45 -0
  70. package/dist/cmd/cloud/sandbox/index.js.map +1 -0
  71. package/dist/cmd/cloud/sandbox/list.d.ts +3 -0
  72. package/dist/cmd/cloud/sandbox/list.d.ts.map +1 -0
  73. package/dist/cmd/cloud/sandbox/list.js +120 -0
  74. package/dist/cmd/cloud/sandbox/list.js.map +1 -0
  75. package/dist/cmd/cloud/sandbox/run.d.ts +3 -0
  76. package/dist/cmd/cloud/sandbox/run.d.ts.map +1 -0
  77. package/dist/cmd/cloud/sandbox/run.js +152 -0
  78. package/dist/cmd/cloud/sandbox/run.js.map +1 -0
  79. package/dist/cmd/cloud/sandbox/snapshot/create.d.ts +3 -0
  80. package/dist/cmd/cloud/sandbox/snapshot/create.d.ts.map +1 -0
  81. package/dist/cmd/cloud/sandbox/snapshot/create.js +65 -0
  82. package/dist/cmd/cloud/sandbox/snapshot/create.js.map +1 -0
  83. package/dist/cmd/cloud/sandbox/snapshot/delete.d.ts +3 -0
  84. package/dist/cmd/cloud/sandbox/snapshot/delete.d.ts.map +1 -0
  85. package/dist/cmd/cloud/sandbox/snapshot/delete.js +66 -0
  86. package/dist/cmd/cloud/sandbox/snapshot/delete.js.map +1 -0
  87. package/dist/cmd/cloud/sandbox/snapshot/get.d.ts +3 -0
  88. package/dist/cmd/cloud/sandbox/snapshot/get.d.ts.map +1 -0
  89. package/dist/cmd/cloud/sandbox/snapshot/get.js +154 -0
  90. package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -0
  91. package/dist/cmd/cloud/sandbox/snapshot/index.d.ts +3 -0
  92. package/dist/cmd/cloud/sandbox/snapshot/index.d.ts.map +1 -0
  93. package/dist/cmd/cloud/sandbox/snapshot/index.js +27 -0
  94. package/dist/cmd/cloud/sandbox/snapshot/index.js.map +1 -0
  95. package/dist/cmd/cloud/sandbox/snapshot/list.d.ts +3 -0
  96. package/dist/cmd/cloud/sandbox/snapshot/list.d.ts.map +1 -0
  97. package/dist/cmd/cloud/sandbox/snapshot/list.js +83 -0
  98. package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -0
  99. package/dist/cmd/cloud/sandbox/snapshot/tag.d.ts +3 -0
  100. package/dist/cmd/cloud/sandbox/snapshot/tag.d.ts.map +1 -0
  101. package/dist/cmd/cloud/sandbox/snapshot/tag.js +63 -0
  102. package/dist/cmd/cloud/sandbox/snapshot/tag.js.map +1 -0
  103. package/dist/cmd/cloud/sandbox/util.d.ts +15 -0
  104. package/dist/cmd/cloud/sandbox/util.d.ts.map +1 -0
  105. package/dist/cmd/cloud/sandbox/util.js +50 -0
  106. package/dist/cmd/cloud/sandbox/util.js.map +1 -0
  107. package/dist/cmd/cloud/secret/delete.d.ts.map +1 -1
  108. package/dist/cmd/cloud/secret/delete.js +3 -3
  109. package/dist/cmd/cloud/secret/delete.js.map +1 -1
  110. package/dist/cmd/cloud/secret/import.js +6 -6
  111. package/dist/cmd/cloud/secret/import.js.map +1 -1
  112. package/dist/cmd/cloud/secret/index.d.ts.map +1 -1
  113. package/dist/cmd/cloud/secret/index.js +1 -0
  114. package/dist/cmd/cloud/secret/index.js.map +1 -1
  115. package/dist/cmd/cloud/secret/pull.d.ts.map +1 -1
  116. package/dist/cmd/cloud/secret/pull.js +7 -9
  117. package/dist/cmd/cloud/secret/pull.js.map +1 -1
  118. package/dist/cmd/cloud/secret/push.js +3 -3
  119. package/dist/cmd/cloud/secret/push.js.map +1 -1
  120. package/dist/cmd/cloud/secret/set.d.ts.map +1 -1
  121. package/dist/cmd/cloud/secret/set.js +3 -3
  122. package/dist/cmd/cloud/secret/set.js.map +1 -1
  123. package/dist/cmd/cloud/storage/create.d.ts.map +1 -1
  124. package/dist/cmd/cloud/storage/create.js +13 -2
  125. package/dist/cmd/cloud/storage/create.js.map +1 -1
  126. package/dist/cmd/cloud/storage/delete.d.ts.map +1 -1
  127. package/dist/cmd/cloud/storage/delete.js +13 -2
  128. package/dist/cmd/cloud/storage/delete.js.map +1 -1
  129. package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
  130. package/dist/cmd/cloud/stream/list.js +2 -13
  131. package/dist/cmd/cloud/stream/list.js.map +1 -1
  132. package/dist/cmd/dev/index.d.ts.map +1 -1
  133. package/dist/cmd/dev/index.js +1 -0
  134. package/dist/cmd/dev/index.js.map +1 -1
  135. package/dist/cmd/profile/create.d.ts.map +1 -1
  136. package/dist/cmd/profile/create.js +1 -0
  137. package/dist/cmd/profile/create.js.map +1 -1
  138. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  139. package/dist/cmd/project/template-flow.js +27 -10
  140. package/dist/cmd/project/template-flow.js.map +1 -1
  141. package/dist/config.d.ts +0 -2
  142. package/dist/config.d.ts.map +1 -1
  143. package/dist/config.js +3 -0
  144. package/dist/config.js.map +1 -1
  145. package/dist/env-util.d.ts +16 -8
  146. package/dist/env-util.d.ts.map +1 -1
  147. package/dist/env-util.js +46 -18
  148. package/dist/env-util.js.map +1 -1
  149. package/dist/tui.d.ts +20 -3
  150. package/dist/tui.d.ts.map +1 -1
  151. package/dist/tui.js +82 -23
  152. package/dist/tui.js.map +1 -1
  153. package/dist/types.d.ts +18 -4
  154. package/dist/types.d.ts.map +1 -1
  155. package/dist/types.js +1 -0
  156. package/dist/types.js.map +1 -1
  157. package/package.json +4 -4
  158. package/src/cli.ts +99 -21
  159. package/src/cmd/build/ast.ts +163 -4
  160. package/src/cmd/build/entry-generator.ts +8 -2
  161. package/src/cmd/build/vite/registry-generator.ts +8 -11
  162. package/src/cmd/cloud/db/create.ts +13 -2
  163. package/src/cmd/cloud/db/delete.ts +15 -2
  164. package/src/cmd/cloud/deploy.ts +3 -3
  165. package/src/cmd/cloud/env/delete.ts +1 -1
  166. package/src/cmd/cloud/env/import.ts +4 -4
  167. package/src/cmd/cloud/env/pull.ts +7 -16
  168. package/src/cmd/cloud/env/push.ts +2 -2
  169. package/src/cmd/cloud/env/set.ts +3 -3
  170. package/src/cmd/cloud/index.ts +2 -0
  171. package/src/cmd/cloud/sandbox/cp.ts +531 -0
  172. package/src/cmd/cloud/sandbox/create.ts +114 -0
  173. package/src/cmd/cloud/sandbox/delete.ts +80 -0
  174. package/src/cmd/cloud/sandbox/exec.ts +254 -0
  175. package/src/cmd/cloud/sandbox/execution/get.ts +106 -0
  176. package/src/cmd/cloud/sandbox/execution/index.ts +25 -0
  177. package/src/cmd/cloud/sandbox/execution/list.ts +111 -0
  178. package/src/cmd/cloud/sandbox/get.ts +104 -0
  179. package/src/cmd/cloud/sandbox/index.ts +46 -0
  180. package/src/cmd/cloud/sandbox/list.ts +129 -0
  181. package/src/cmd/cloud/sandbox/run.ts +170 -0
  182. package/src/cmd/cloud/sandbox/snapshot/create.ts +71 -0
  183. package/src/cmd/cloud/sandbox/snapshot/delete.ts +74 -0
  184. package/src/cmd/cloud/sandbox/snapshot/get.ts +188 -0
  185. package/src/cmd/cloud/sandbox/snapshot/index.ts +28 -0
  186. package/src/cmd/cloud/sandbox/snapshot/list.ts +90 -0
  187. package/src/cmd/cloud/sandbox/snapshot/tag.ts +70 -0
  188. package/src/cmd/cloud/sandbox/util.ts +59 -0
  189. package/src/cmd/cloud/secret/delete.ts +8 -3
  190. package/src/cmd/cloud/secret/import.ts +6 -6
  191. package/src/cmd/cloud/secret/index.ts +1 -0
  192. package/src/cmd/cloud/secret/pull.ts +7 -16
  193. package/src/cmd/cloud/secret/push.ts +3 -3
  194. package/src/cmd/cloud/secret/set.ts +8 -3
  195. package/src/cmd/cloud/storage/create.ts +15 -2
  196. package/src/cmd/cloud/storage/delete.ts +15 -2
  197. package/src/cmd/cloud/stream/list.ts +2 -9
  198. package/src/cmd/dev/index.ts +1 -0
  199. package/src/cmd/profile/create.ts +1 -0
  200. package/src/cmd/project/template-flow.ts +29 -13
  201. package/src/config.ts +3 -0
  202. package/src/env-util.ts +52 -21
  203. package/src/tui.ts +131 -39
  204. package/src/types.ts +18 -16
@@ -0,0 +1,104 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { createSandboxClient } from './util';
5
+ import { getCommand } from '../../../command-prefix';
6
+ import { sandboxGet } from '@agentuity/server';
7
+
8
+ const SandboxGetResponseSchema = z.object({
9
+ sandboxId: z.string().describe('Sandbox ID'),
10
+ status: z.string().describe('Current status'),
11
+ createdAt: z.string().describe('Creation timestamp'),
12
+ region: z.string().optional().describe('Region where sandbox is running'),
13
+ snapshotId: z.string().optional().describe('Snapshot ID sandbox was created from'),
14
+ snapshotTag: z.string().optional().describe('Snapshot tag sandbox was created from'),
15
+ executions: z.number().describe('Number of executions'),
16
+ stdoutStreamUrl: z.string().optional().describe('URL to stdout output stream'),
17
+ stderrStreamUrl: z.string().optional().describe('URL to stderr output stream'),
18
+ dependencies: z.array(z.string()).optional().describe('Apt packages installed'),
19
+ });
20
+
21
+ export const getSubcommand = createCommand({
22
+ name: 'get',
23
+ aliases: ['info', 'show'],
24
+ description: 'Get information about a sandbox',
25
+ tags: ['read-only', 'fast', 'requires-auth'],
26
+ requires: { auth: true, region: true, org: true },
27
+ idempotent: true,
28
+ examples: [
29
+ {
30
+ command: getCommand('cloud sandbox get abc123'),
31
+ description: 'Get sandbox information',
32
+ },
33
+ ],
34
+ schema: {
35
+ args: z.object({
36
+ sandboxId: z.string().describe('Sandbox ID'),
37
+ }),
38
+ response: SandboxGetResponseSchema,
39
+ },
40
+
41
+ async handler(ctx) {
42
+ const { args, options, auth, region, logger, orgId } = ctx;
43
+ const client = createSandboxClient(logger, auth, region);
44
+
45
+ const result = await sandboxGet(client, { sandboxId: args.sandboxId, orgId });
46
+
47
+ if (!options.json) {
48
+ const statusColor =
49
+ result.status === 'running'
50
+ ? tui.colorSuccess
51
+ : result.status === 'idle'
52
+ ? tui.colorWarning
53
+ : result.status === 'failed'
54
+ ? tui.colorError
55
+ : tui.colorMuted;
56
+
57
+ console.log(`${tui.muted('Sandbox:')} ${tui.bold(result.sandboxId)}`);
58
+ console.log(`${tui.muted('Status:')} ${statusColor(result.status)}`);
59
+ console.log(`${tui.muted('Created:')} ${result.createdAt}`);
60
+ if (result.region) {
61
+ console.log(`${tui.muted('Region:')} ${result.region}`);
62
+ }
63
+ if (result.snapshotId || result.snapshotTag) {
64
+ const snapshotDisplay = result.snapshotTag
65
+ ? `${result.snapshotTag} ${tui.muted('(' + result.snapshotId + ')')}`
66
+ : result.snapshotId;
67
+ console.log(`${tui.muted('Snapshot:')} ${snapshotDisplay}`);
68
+ }
69
+ console.log(`${tui.muted('Executions:')} ${result.executions}`);
70
+ if (
71
+ result.stdoutStreamUrl &&
72
+ result.stderrStreamUrl &&
73
+ result.stdoutStreamUrl === result.stderrStreamUrl
74
+ ) {
75
+ console.log(`${tui.muted('Stream:')} ${tui.link(result.stdoutStreamUrl)}`);
76
+ } else {
77
+ if (result.stdoutStreamUrl) {
78
+ console.log(`${tui.muted('Stream (stdout):')} ${tui.link(result.stdoutStreamUrl)}`);
79
+ }
80
+ if (result.stderrStreamUrl) {
81
+ console.log(`${tui.muted('Stream (stderr):')} ${tui.link(result.stderrStreamUrl)}`);
82
+ }
83
+ }
84
+ if (result.dependencies && result.dependencies.length > 0) {
85
+ console.log(`${tui.muted('Dependencies:')} ${result.dependencies.join(', ')}`);
86
+ }
87
+ }
88
+
89
+ return {
90
+ sandboxId: result.sandboxId,
91
+ status: result.status,
92
+ createdAt: result.createdAt,
93
+ region: result.region,
94
+ snapshotId: result.snapshotId,
95
+ snapshotTag: result.snapshotTag,
96
+ executions: result.executions,
97
+ stdoutStreamUrl: result.stdoutStreamUrl,
98
+ stderrStreamUrl: result.stderrStreamUrl,
99
+ dependencies: result.dependencies,
100
+ };
101
+ },
102
+ });
103
+
104
+ export default getSubcommand;
@@ -0,0 +1,46 @@
1
+ import { createCommand } from '../../../types';
2
+ import { runSubcommand } from './run';
3
+ import { createSubcommand } from './create';
4
+ import { execSubcommand } from './exec';
5
+ import { listSubcommand } from './list';
6
+ import { getSubcommand } from './get';
7
+ import { deleteSubcommand } from './delete';
8
+ import { snapshotCommand } from './snapshot';
9
+ import { cpSubcommand } from './cp';
10
+ import { command as executionCommand } from './execution';
11
+ import { getCommand } from '../../../command-prefix';
12
+
13
+ export const command = createCommand({
14
+ name: 'sandbox',
15
+ aliases: ['sb'],
16
+ description: 'Manage sandboxes for isolated code execution',
17
+ tags: ['slow', 'requires-auth'],
18
+ examples: [
19
+ {
20
+ command: getCommand('cloud sandbox run -- echo "hello"'),
21
+ description: 'Run a one-shot command in a sandbox',
22
+ },
23
+ {
24
+ command: getCommand('cloud sandbox create'),
25
+ description: 'Create an interactive sandbox',
26
+ },
27
+ {
28
+ command: getCommand('cloud sandbox list'),
29
+ description: 'List all sandboxes',
30
+ },
31
+ ],
32
+ subcommands: [
33
+ runSubcommand,
34
+ createSubcommand,
35
+ execSubcommand,
36
+ listSubcommand,
37
+ getSubcommand,
38
+ deleteSubcommand,
39
+ snapshotCommand,
40
+ cpSubcommand,
41
+ executionCommand,
42
+ ],
43
+ requires: { auth: true, region: true, org: true },
44
+ });
45
+
46
+ export default command;
@@ -0,0 +1,129 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { getCommand } from '../../../command-prefix';
5
+ import { sandboxList } from '@agentuity/server';
6
+ import { createSandboxClient } from './util';
7
+ import type { SandboxStatus } from '@agentuity/core';
8
+
9
+ const SandboxInfoSchema = z.object({
10
+ sandboxId: z.string().describe('Sandbox ID'),
11
+ status: z.string().describe('Current status'),
12
+ createdAt: z.string().describe('Creation timestamp'),
13
+ region: z.string().optional().describe('Region where sandbox is running'),
14
+ snapshotId: z.string().optional().describe('Snapshot ID sandbox was created from'),
15
+ snapshotTag: z.string().optional().describe('Snapshot tag sandbox was created from'),
16
+ executions: z.number().describe('Number of executions'),
17
+ });
18
+
19
+ const SandboxListResponseSchema = z.object({
20
+ sandboxes: z.array(SandboxInfoSchema).describe('List of sandboxes'),
21
+ total: z.number().describe('Total count'),
22
+ });
23
+
24
+ export const listSubcommand = createCommand({
25
+ name: 'list',
26
+ aliases: ['ls'],
27
+ description: 'List sandboxes with optional filtering',
28
+ tags: ['read-only', 'slow', 'requires-auth'],
29
+ requires: { auth: true, region: true, org: true },
30
+ optional: { project: true },
31
+ idempotent: true,
32
+ pagination: {
33
+ supported: true,
34
+ defaultLimit: 50,
35
+ maxLimit: 100,
36
+ parameters: {
37
+ limit: 'limit',
38
+ offset: 'offset',
39
+ },
40
+ },
41
+ examples: [
42
+ {
43
+ command: getCommand('cloud sandbox list'),
44
+ description: 'List all sandboxes',
45
+ },
46
+ {
47
+ command: getCommand('cloud sandbox list --status running'),
48
+ description: 'List running sandboxes',
49
+ },
50
+ {
51
+ command: getCommand('cloud sandbox list --project-id proj_123'),
52
+ description: 'List sandboxes for a specific project',
53
+ },
54
+ {
55
+ command: getCommand('cloud sandbox list --limit 10 --offset 20'),
56
+ description: 'List with pagination',
57
+ },
58
+ ],
59
+ schema: {
60
+ options: z.object({
61
+ status: z
62
+ .enum(['creating', 'idle', 'running', 'terminated', 'failed'])
63
+ .optional()
64
+ .describe('Filter by status'),
65
+ projectId: z.string().optional().describe('Filter by project ID'),
66
+ limit: z.number().optional().describe('Maximum number of results (default: 50, max: 100)'),
67
+ offset: z.number().optional().describe('Pagination offset'),
68
+ }),
69
+ response: SandboxListResponseSchema,
70
+ },
71
+
72
+ async handler(ctx) {
73
+ const { opts, options, auth, project, region, logger, orgId } = ctx;
74
+ const client = createSandboxClient(logger, auth, region);
75
+
76
+ const projectId = opts.projectId || project?.projectId;
77
+
78
+ const result = await sandboxList(client, {
79
+ orgId,
80
+ projectId,
81
+ status: opts.status as SandboxStatus | undefined,
82
+ limit: opts.limit,
83
+ offset: opts.offset,
84
+ });
85
+
86
+ if (!options.json) {
87
+ if (result.sandboxes.length === 0) {
88
+ tui.info('No sandboxes found');
89
+ } else {
90
+ const tableData = result.sandboxes.map((sandbox) => {
91
+ const snapshotDisplay = sandbox.snapshotTag
92
+ ? `${sandbox.snapshotTag} (${sandbox.snapshotId})`
93
+ : sandbox.snapshotId || '-';
94
+ return {
95
+ ID: sandbox.sandboxId,
96
+ Status: sandbox.status,
97
+ 'Created At': sandbox.createdAt,
98
+ Snapshot: snapshotDisplay,
99
+ Executions: sandbox.executions,
100
+ };
101
+ });
102
+ tui.table(tableData, [
103
+ { name: 'ID', alignment: 'left' },
104
+ { name: 'Status', alignment: 'left' },
105
+ { name: 'Created At', alignment: 'left' },
106
+ { name: 'Snapshot', alignment: 'left' },
107
+ { name: 'Executions', alignment: 'right' },
108
+ ]);
109
+
110
+ tui.info(`Total: ${result.total} ${tui.plural(result.total, 'sandbox', 'sandboxes')}`);
111
+ }
112
+ }
113
+
114
+ return {
115
+ sandboxes: result.sandboxes.map((s) => ({
116
+ sandboxId: s.sandboxId,
117
+ status: s.status,
118
+ createdAt: s.createdAt,
119
+ region: s.region,
120
+ snapshotId: s.snapshotId,
121
+ snapshotTag: s.snapshotTag,
122
+ executions: s.executions,
123
+ })),
124
+ total: result.total,
125
+ };
126
+ },
127
+ });
128
+
129
+ export default listSubcommand;
@@ -0,0 +1,170 @@
1
+ import { z } from 'zod';
2
+ import { Writable } from 'node:stream';
3
+ import { createCommand } from '../../../types';
4
+ import * as tui from '../../../tui';
5
+ import { createSandboxClient, parseFileArgs } from './util';
6
+ import { getCommand } from '../../../command-prefix';
7
+ import { sandboxRun } from '@agentuity/server';
8
+
9
+ const SandboxRunResponseSchema = z.object({
10
+ sandboxId: z.string().describe('Sandbox ID'),
11
+ exitCode: z.number().describe('Exit code from the process'),
12
+ durationMs: z.number().describe('Duration in milliseconds'),
13
+ output: z.string().optional().describe('Combined stdout/stderr output'),
14
+ });
15
+
16
+ export const runSubcommand = createCommand({
17
+ name: 'run',
18
+ description: 'Run a one-shot command in a sandbox (creates, executes, destroys)',
19
+ tags: ['slow', 'requires-auth'],
20
+ requires: { auth: true, region: true, org: true },
21
+ examples: [
22
+ {
23
+ command: getCommand('cloud sandbox run -- echo "hello world"'),
24
+ description: 'Run a simple command',
25
+ },
26
+ {
27
+ command: getCommand('cloud sandbox run --memory 1Gi --cpu 1000m -- bun run index.ts'),
28
+ description: 'Run with resource limits',
29
+ },
30
+ {
31
+ command: getCommand('cloud sandbox run --network -- curl https://api.example.com'),
32
+ description: 'Run with network access enabled',
33
+ },
34
+ ],
35
+ schema: {
36
+ args: z.object({
37
+ command: z.array(z.string()).describe('Command and arguments to execute'),
38
+ }),
39
+ options: z.object({
40
+ memory: z.string().optional().describe('Memory limit (e.g., "500Mi", "1Gi")'),
41
+ cpu: z.string().optional().describe('CPU limit in millicores (e.g., "500m", "1000m")'),
42
+ disk: z.string().optional().describe('Disk limit (e.g., "500Mi", "1Gi")'),
43
+ network: z.boolean().default(false).optional().describe('Enable outbound network access'),
44
+ timeout: z.string().optional().describe('Execution timeout (e.g., "5m", "1h")'),
45
+ env: z.array(z.string()).optional().describe('Environment variables (KEY=VALUE)'),
46
+ file: z
47
+ .array(z.string())
48
+ .optional()
49
+ .describe('Files to create in sandbox (sandbox-path:local-path)'),
50
+ timestamps: z
51
+ .boolean()
52
+ .default(false)
53
+ .optional()
54
+ .describe('Include timestamps in output (default: true)'),
55
+ snapshot: z.string().optional().describe('Snapshot ID or tag to restore from'),
56
+ dependency: z
57
+ .array(z.string())
58
+ .optional()
59
+ .describe('Apt packages to install (can be specified multiple times)'),
60
+ }),
61
+ response: SandboxRunResponseSchema,
62
+ },
63
+
64
+ async handler(ctx) {
65
+ const { args, opts, options, auth, region, logger, orgId } = ctx;
66
+ const client = createSandboxClient(logger, auth, region);
67
+ const started = Date.now();
68
+
69
+ const envMap: Record<string, string> = {};
70
+ if (opts.env) {
71
+ for (const e of opts.env) {
72
+ const [key, ...valueParts] = e.split('=');
73
+ if (key) {
74
+ envMap[key] = valueParts.join('=');
75
+ }
76
+ }
77
+ }
78
+
79
+ const files = parseFileArgs(opts.file);
80
+ const hasFiles = files.length > 0;
81
+
82
+ const abortController = new AbortController();
83
+ const handleSignal = () => {
84
+ abortController.abort();
85
+ };
86
+ process.on('SIGINT', handleSignal);
87
+ process.on('SIGTERM', handleSignal);
88
+
89
+ const outputChunks: string[] = [];
90
+
91
+ // Determine if we have stdin data (not a TTY means piped input)
92
+ const hasStdin = !process.stdin.isTTY;
93
+
94
+ // For JSON output, we need to capture output instead of streaming to process
95
+ const stdout = options.json
96
+ ? createCaptureStream((chunk) => outputChunks.push(chunk))
97
+ : process.stdout;
98
+ const stderr = options.json
99
+ ? createCaptureStream((chunk) => outputChunks.push(chunk))
100
+ : process.stderr;
101
+
102
+ try {
103
+ const result = await sandboxRun(client, {
104
+ options: {
105
+ command: {
106
+ exec: args.command,
107
+ files: hasFiles ? files : undefined,
108
+ },
109
+ resources:
110
+ opts.memory || opts.cpu || opts.disk
111
+ ? {
112
+ memory: opts.memory,
113
+ cpu: opts.cpu,
114
+ disk: opts.disk,
115
+ }
116
+ : undefined,
117
+ network: opts.network ? { enabled: true } : undefined,
118
+ timeout: opts.timeout ? { execution: opts.timeout } : undefined,
119
+ env: Object.keys(envMap).length > 0 ? envMap : undefined,
120
+ stream: opts.timestamps !== undefined ? { timestamps: opts.timestamps } : undefined,
121
+ snapshot: opts.snapshot,
122
+ dependencies: opts.dependency,
123
+ },
124
+ orgId,
125
+ region,
126
+ apiKey: auth.apiKey,
127
+ signal: abortController.signal,
128
+ stdin: hasStdin ? process.stdin : undefined,
129
+ stdout,
130
+ stderr,
131
+ logger,
132
+ });
133
+
134
+ const duration = Date.now() - started;
135
+ const output = outputChunks.join('');
136
+
137
+ if (!options.json) {
138
+ if (result.exitCode !== 0) {
139
+ tui.error(`failed with exit code ${result.exitCode} in ${duration}ms`);
140
+ }
141
+ }
142
+
143
+ return {
144
+ sandboxId: result.sandboxId,
145
+ exitCode: result.exitCode,
146
+ durationMs: result.durationMs,
147
+ output: options.json ? output : undefined,
148
+ };
149
+ } finally {
150
+ process.off('SIGINT', handleSignal);
151
+ process.off('SIGTERM', handleSignal);
152
+ }
153
+ },
154
+ });
155
+
156
+ function createCaptureStream(onChunk: (chunk: string) => void): Writable {
157
+ return new Writable({
158
+ write(
159
+ chunk: Buffer | string,
160
+ _encoding: string,
161
+ callback: (error?: Error | null) => void
162
+ ): void {
163
+ const text = typeof chunk === 'string' ? chunk : chunk.toString('utf-8');
164
+ onChunk(text);
165
+ callback();
166
+ },
167
+ });
168
+ }
169
+
170
+ export default runSubcommand;
@@ -0,0 +1,71 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../../types';
3
+ import * as tui from '../../../../tui';
4
+ import { createSandboxClient } from '../util';
5
+ import { getCommand } from '../../../../command-prefix';
6
+ import { snapshotCreate } from '@agentuity/server';
7
+
8
+ const SnapshotCreateResponseSchema = z.object({
9
+ snapshotId: z.string().describe('Snapshot ID'),
10
+ sandboxId: z.string().describe('Source sandbox ID'),
11
+ tag: z.string().optional().nullable().describe('Snapshot tag'),
12
+ sizeBytes: z.number().describe('Snapshot size in bytes'),
13
+ fileCount: z.number().describe('Number of files in snapshot'),
14
+ createdAt: z.string().describe('Snapshot creation timestamp'),
15
+ });
16
+
17
+ export const createSubcommand = createCommand({
18
+ name: 'create',
19
+ description: 'Create a snapshot from a sandbox',
20
+ tags: ['slow', 'requires-auth'],
21
+ requires: { auth: true, region: true, org: true },
22
+ examples: [
23
+ {
24
+ command: getCommand('cloud sandbox snapshot create sbx_abc123'),
25
+ description: 'Create a snapshot from a sandbox',
26
+ },
27
+ {
28
+ command: getCommand('cloud sandbox snapshot create sbx_abc123 --tag latest'),
29
+ description: 'Create a tagged snapshot',
30
+ },
31
+ ],
32
+ schema: {
33
+ args: z.object({
34
+ sandboxId: z.string().describe('Sandbox ID to snapshot'),
35
+ }),
36
+ options: z.object({
37
+ tag: z.string().optional().describe('Tag for the snapshot'),
38
+ }),
39
+ response: SnapshotCreateResponseSchema,
40
+ },
41
+
42
+ async handler(ctx) {
43
+ const { args, opts, options, auth, region, logger, orgId } = ctx;
44
+ const client = createSandboxClient(logger, auth, region);
45
+
46
+ const snapshot = await snapshotCreate(client, {
47
+ sandboxId: args.sandboxId,
48
+ tag: opts.tag,
49
+ orgId,
50
+ });
51
+
52
+ if (!options.json) {
53
+ tui.success(`created snapshot ${tui.bold(snapshot.snapshotId)}`);
54
+ tui.info(`Size: ${tui.formatBytes(snapshot.sizeBytes)}, Files: ${snapshot.fileCount}`);
55
+ if (snapshot.tag) {
56
+ tui.info(`Tag: ${snapshot.tag}`);
57
+ }
58
+ }
59
+
60
+ return {
61
+ snapshotId: snapshot.snapshotId,
62
+ sandboxId: snapshot.sandboxId,
63
+ tag: snapshot.tag ?? undefined,
64
+ sizeBytes: snapshot.sizeBytes,
65
+ fileCount: snapshot.fileCount,
66
+ createdAt: snapshot.createdAt,
67
+ };
68
+ },
69
+ });
70
+
71
+ export default createSubcommand;
@@ -0,0 +1,74 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../../types';
3
+ import * as tui from '../../../../tui';
4
+ import { createSandboxClient } from '../util';
5
+ import { getCommand } from '../../../../command-prefix';
6
+ import { snapshotDelete } from '@agentuity/server';
7
+
8
+ const SnapshotDeleteResponseSchema = z.object({
9
+ success: z.boolean().describe('Whether the operation succeeded'),
10
+ snapshotId: z.string().describe('Deleted snapshot ID'),
11
+ message: z.string().optional().describe('Status message'),
12
+ });
13
+
14
+ export const deleteSubcommand = createCommand({
15
+ name: 'delete',
16
+ aliases: ['del', 'rm', 'remove'],
17
+ description: 'Delete a snapshot',
18
+ tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth'],
19
+ requires: { auth: true, region: true, org: true },
20
+ idempotent: true,
21
+ examples: [
22
+ {
23
+ command: getCommand('cloud sandbox snapshot delete snp_abc123'),
24
+ description: 'Delete a snapshot',
25
+ },
26
+ {
27
+ command: getCommand('cloud sandbox snapshot rm snp_abc123 --confirm'),
28
+ description: 'Delete without confirmation prompt',
29
+ },
30
+ ],
31
+ schema: {
32
+ args: z.object({
33
+ snapshotId: z.string().describe('Snapshot ID to delete'),
34
+ }),
35
+ options: z.object({
36
+ confirm: z.boolean().optional().default(false).describe('Skip confirmation prompt'),
37
+ }),
38
+ response: SnapshotDeleteResponseSchema,
39
+ },
40
+
41
+ async handler(ctx) {
42
+ const { args, options, opts, auth, region, logger, orgId } = ctx;
43
+
44
+ if (!opts.confirm) {
45
+ const confirmed = await tui.confirm(`Delete snapshot "${args.snapshotId}"?`, false);
46
+ if (!confirmed) {
47
+ logger.info('Cancelled');
48
+ return {
49
+ success: false,
50
+ snapshotId: args.snapshotId,
51
+ message: 'Cancelled',
52
+ };
53
+ }
54
+ }
55
+
56
+ const client = createSandboxClient(logger, auth, region);
57
+
58
+ await snapshotDelete(client, {
59
+ snapshotId: args.snapshotId,
60
+ orgId,
61
+ });
62
+
63
+ if (!options.json) {
64
+ tui.success(`deleted snapshot ${tui.bold(args.snapshotId)}`);
65
+ }
66
+
67
+ return {
68
+ success: true,
69
+ snapshotId: args.snapshotId,
70
+ };
71
+ },
72
+ });
73
+
74
+ export default deleteSubcommand;