@agentuity/cli 2.0.11 → 2.0.12
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/cache/resource-region.d.ts.map +1 -1
- package/dist/cache/resource-region.js +48 -25
- package/dist/cache/resource-region.js.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.d.ts +20 -0
- package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.js +62 -4
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
- package/dist/cmd/build/vite/index.d.ts +0 -1
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +0 -1
- package/dist/cmd/build/vite/index.js.map +1 -1
- package/dist/cmd/build/vite/static-renderer.d.ts +17 -0
- package/dist/cmd/build/vite/static-renderer.d.ts.map +1 -1
- package/dist/cmd/build/vite/static-renderer.js +18 -6
- package/dist/cmd/build/vite/static-renderer.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.js +34 -27
- package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.d.ts +9 -0
- package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.js +5 -1
- package/dist/cmd/build/vite/vite-asset-server.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +12 -1
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/build/vite/ws-proxy.d.ts +15 -1
- package/dist/cmd/build/vite/ws-proxy.d.ts.map +1 -1
- package/dist/cmd/build/vite/ws-proxy.js +33 -0
- package/dist/cmd/build/vite/ws-proxy.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +98 -39
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/create.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/delete.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/list.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/restore.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/restore.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/restore.js.map +1 -1
- package/dist/cmd/cloud/sandbox/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/create.js +13 -4
- package/dist/cmd/cloud/sandbox/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.js +3 -4
- package/dist/cmd/cloud/sandbox/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/env.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/env.js +3 -5
- package/dist/cmd/cloud/sandbox/env.js.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.js +114 -41
- package/dist/cmd/cloud/sandbox/exec.js.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/list.js +3 -5
- package/dist/cmd/cloud/sandbox/execution/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/cp.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/cp.js +61 -113
- package/dist/cmd/cloud/sandbox/fs/cp.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/download.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/download.js +11 -22
- package/dist/cmd/cloud/sandbox/fs/download.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/ls.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/ls.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/ls.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/mkdir.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/mkdir.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/mkdir.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rm.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rm.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/rm.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rmdir.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rmdir.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/rmdir.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/upload.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/upload.js +7 -8
- package/dist/cmd/cloud/sandbox/fs/upload.js.map +1 -1
- package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/get.js +21 -7
- package/dist/cmd/cloud/sandbox/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/create.js +3 -4
- package/dist/cmd/cloud/sandbox/job/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/destroy.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/destroy.js +3 -4
- package/dist/cmd/cloud/sandbox/job/destroy.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/get.js +3 -4
- package/dist/cmd/cloud/sandbox/job/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/list.js +3 -4
- package/dist/cmd/cloud/sandbox/job/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/logs.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/logs.js +4 -4
- package/dist/cmd/cloud/sandbox/job/logs.js.map +1 -1
- package/dist/cmd/cloud/sandbox/pause.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/pause.js +21 -5
- package/dist/cmd/cloud/sandbox/pause.js.map +1 -1
- package/dist/cmd/cloud/sandbox/resume.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/resume.js +3 -4
- package/dist/cmd/cloud/sandbox/resume.js.map +1 -1
- package/dist/cmd/cloud/sandbox/run.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/run.js +36 -7
- package/dist/cmd/cloud/sandbox/run.js.map +1 -1
- package/dist/cmd/cloud/sandbox/util.d.ts +19 -0
- package/dist/cmd/cloud/sandbox/util.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/util.js +40 -2
- package/dist/cmd/cloud/sandbox/util.js.map +1 -1
- package/dist/cmd/coder/create.js +7 -7
- package/dist/cmd/coder/create.js.map +1 -1
- package/dist/cmd/coder/start.d.ts.map +1 -1
- package/dist/cmd/coder/start.js +3 -0
- package/dist/cmd/coder/start.js.map +1 -1
- package/dist/cmd/coder/tui-init.js +1 -1
- package/dist/cmd/coder/tui-init.js.map +1 -1
- package/dist/cmd/coder/update.js +8 -8
- package/dist/cmd/coder/update.js.map +1 -1
- package/dist/cmd/coder/workspace/create.d.ts.map +1 -1
- package/dist/cmd/coder/workspace/create.js +49 -21
- package/dist/cmd/coder/workspace/create.js.map +1 -1
- package/dist/cmd/coder/workspace/index.d.ts.map +1 -1
- package/dist/cmd/coder/workspace/index.js +1 -1
- package/dist/cmd/coder/workspace/index.js.map +1 -1
- package/dist/cmd/dev/dev-lock.d.ts.map +1 -1
- package/dist/cmd/dev/dev-lock.js +43 -17
- package/dist/cmd/dev/dev-lock.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +211 -125
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/dev/process-manager.d.ts +41 -1
- package/dist/cmd/dev/process-manager.d.ts.map +1 -1
- package/dist/cmd/dev/process-manager.js +160 -31
- package/dist/cmd/dev/process-manager.js.map +1 -1
- package/dist/cmd/project/create.d.ts.map +1 -1
- package/dist/cmd/project/create.js +0 -2
- package/dist/cmd/project/create.js.map +1 -1
- package/dist/cmd/project/index.d.ts.map +1 -1
- package/dist/cmd/project/index.js +0 -3
- package/dist/cmd/project/index.js.map +1 -1
- package/dist/cmd/project/template-flow.d.ts +0 -1
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.js +1 -124
- package/dist/cmd/project/template-flow.js.map +1 -1
- package/package.json +7 -7
- package/src/cache/resource-region.ts +68 -44
- package/src/cmd/ai/prompt/web.md +43 -17
- package/src/cmd/build/vite/bun-dev-server.ts +92 -6
- package/src/cmd/build/vite/index.ts +0 -1
- package/src/cmd/build/vite/static-renderer.ts +18 -7
- package/src/cmd/build/vite/vite-asset-server-config.ts +37 -27
- package/src/cmd/build/vite/vite-asset-server.ts +5 -1
- package/src/cmd/build/vite/vite-builder.ts +12 -1
- package/src/cmd/build/vite/ws-proxy.ts +52 -3
- package/src/cmd/cloud/deploy.ts +117 -49
- package/src/cmd/cloud/sandbox/checkpoint/create.ts +10 -4
- package/src/cmd/cloud/sandbox/checkpoint/delete.ts +10 -4
- package/src/cmd/cloud/sandbox/checkpoint/list.ts +10 -4
- package/src/cmd/cloud/sandbox/checkpoint/restore.ts +10 -4
- package/src/cmd/cloud/sandbox/create.ts +14 -4
- package/src/cmd/cloud/sandbox/delete.ts +10 -4
- package/src/cmd/cloud/sandbox/env.ts +10 -5
- package/src/cmd/cloud/sandbox/exec.ts +157 -42
- package/src/cmd/cloud/sandbox/execution/list.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/cp.ts +94 -126
- package/src/cmd/cloud/sandbox/fs/download.ts +18 -25
- package/src/cmd/cloud/sandbox/fs/ls.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/mkdir.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/rm.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/rmdir.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/upload.ts +14 -8
- package/src/cmd/cloud/sandbox/get.ts +28 -7
- package/src/cmd/cloud/sandbox/job/create.ts +10 -4
- package/src/cmd/cloud/sandbox/job/destroy.ts +10 -4
- package/src/cmd/cloud/sandbox/job/get.ts +10 -4
- package/src/cmd/cloud/sandbox/job/list.ts +10 -4
- package/src/cmd/cloud/sandbox/job/logs.ts +11 -4
- package/src/cmd/cloud/sandbox/pause.ts +31 -5
- package/src/cmd/cloud/sandbox/resume.ts +10 -4
- package/src/cmd/cloud/sandbox/run.ts +49 -11
- package/src/cmd/cloud/sandbox/util.ts +63 -2
- package/src/cmd/coder/create.ts +8 -8
- package/src/cmd/coder/start.ts +3 -0
- package/src/cmd/coder/tui-init.ts +1 -1
- package/src/cmd/coder/update.ts +7 -7
- package/src/cmd/coder/workspace/create.ts +77 -26
- package/src/cmd/coder/workspace/index.ts +3 -1
- package/src/cmd/dev/dev-lock.ts +50 -16
- package/src/cmd/dev/index.ts +249 -134
- package/src/cmd/dev/process-manager.ts +173 -33
- package/src/cmd/project/create.ts +0 -2
- package/src/cmd/project/index.ts +0 -3
- package/src/cmd/project/template-flow.ts +0 -147
- package/dist/cmd/build/vite/public-asset-path-plugin.d.ts +0 -45
- package/dist/cmd/build/vite/public-asset-path-plugin.d.ts.map +0 -1
- package/dist/cmd/build/vite/public-asset-path-plugin.js +0 -166
- package/dist/cmd/build/vite/public-asset-path-plugin.js.map +0 -1
- package/dist/cmd/project/auth/generate.d.ts +0 -5
- package/dist/cmd/project/auth/generate.d.ts.map +0 -1
- package/dist/cmd/project/auth/generate.js +0 -102
- package/dist/cmd/project/auth/generate.js.map +0 -1
- package/dist/cmd/project/auth/index.d.ts +0 -2
- package/dist/cmd/project/auth/index.d.ts.map +0 -1
- package/dist/cmd/project/auth/index.js +0 -21
- package/dist/cmd/project/auth/index.js.map +0 -1
- package/dist/cmd/project/auth/init.d.ts +0 -2
- package/dist/cmd/project/auth/init.d.ts.map +0 -1
- package/dist/cmd/project/auth/init.js +0 -213
- package/dist/cmd/project/auth/init.js.map +0 -1
- package/dist/cmd/project/auth/shared.d.ts +0 -93
- package/dist/cmd/project/auth/shared.d.ts.map +0 -1
- package/dist/cmd/project/auth/shared.js +0 -475
- package/dist/cmd/project/auth/shared.js.map +0 -1
- package/src/cmd/build/vite/public-asset-path-plugin.ts +0 -209
- package/src/cmd/project/auth/generate.ts +0 -116
- package/src/cmd/project/auth/index.ts +0 -21
- package/src/cmd/project/auth/init.ts +0 -256
- package/src/cmd/project/auth/shared.ts +0 -591
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { createCommand } from '../../../types';
|
|
3
3
|
import * as tui from '../../../tui';
|
|
4
|
-
import { createSandboxClient } from './util';
|
|
4
|
+
import { createSandboxClient, resolveSandboxTarget } from './util';
|
|
5
5
|
import { getCommand } from '../../../command-prefix';
|
|
6
|
-
import { sandboxSetEnv
|
|
6
|
+
import { sandboxSetEnv } from '@agentuity/server';
|
|
7
7
|
|
|
8
8
|
export const envSubcommand = createCommand({
|
|
9
9
|
name: 'env',
|
|
@@ -44,9 +44,14 @@ export const envSubcommand = createCommand({
|
|
|
44
44
|
async handler(ctx) {
|
|
45
45
|
const { args, opts, options, auth, logger, apiClient } = ctx;
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
const { region, orgId } = await resolveSandboxTarget(
|
|
48
|
+
logger,
|
|
49
|
+
auth,
|
|
50
|
+
apiClient,
|
|
51
|
+
args.sandboxId,
|
|
52
|
+
ctx.config?.name ?? 'production',
|
|
53
|
+
ctx.config
|
|
54
|
+
);
|
|
50
55
|
|
|
51
56
|
const client = createSandboxClient(logger, auth, region);
|
|
52
57
|
|
|
@@ -3,12 +3,14 @@ import { Writable } from 'node:stream';
|
|
|
3
3
|
import { ErrorCode } from '../../../errors';
|
|
4
4
|
import { createCommand } from '../../../types';
|
|
5
5
|
import * as tui from '../../../tui';
|
|
6
|
-
import { createSandboxClient } from './util';
|
|
6
|
+
import { createSandboxClient, detectNullStream, resolveSandboxTarget } from './util';
|
|
7
7
|
import { getCommand } from '../../../command-prefix';
|
|
8
|
-
import { sandboxExecute, executionGet
|
|
8
|
+
import { sandboxExecute, executionGet } from '@agentuity/server';
|
|
9
9
|
import { streamUrlToWritable } from '../../../utils/stream-url';
|
|
10
10
|
|
|
11
11
|
const EXECUTION_WAIT_DURATION = '5m';
|
|
12
|
+
const EMPTY_STREAM_FAST_POLL_MS = 100;
|
|
13
|
+
const EMPTY_STREAM_FAST_TIMEOUT_MS = 2000;
|
|
12
14
|
|
|
13
15
|
const SandboxExecResponseSchema = z.object({
|
|
14
16
|
executionId: z.string().describe('Unique execution identifier'),
|
|
@@ -63,6 +65,11 @@ export const execSubcommand = createCommand({
|
|
|
63
65
|
.default(false)
|
|
64
66
|
.optional()
|
|
65
67
|
.describe('Include timestamps in output (default: false)'),
|
|
68
|
+
quiet: z
|
|
69
|
+
.boolean()
|
|
70
|
+
.default(false)
|
|
71
|
+
.optional()
|
|
72
|
+
.describe('Suppress output (do not create stdout/stderr streams)'),
|
|
66
73
|
}),
|
|
67
74
|
response: SandboxExecResponseSchema,
|
|
68
75
|
},
|
|
@@ -79,12 +86,46 @@ export const execSubcommand = createCommand({
|
|
|
79
86
|
}
|
|
80
87
|
}
|
|
81
88
|
|
|
82
|
-
const
|
|
83
|
-
|
|
89
|
+
const { region, orgId } = await resolveSandboxTarget(
|
|
90
|
+
logger,
|
|
91
|
+
auth,
|
|
92
|
+
apiClient,
|
|
93
|
+
args.sandboxId,
|
|
94
|
+
ctx.config?.name ?? 'production',
|
|
95
|
+
ctx.config
|
|
96
|
+
);
|
|
84
97
|
|
|
85
98
|
const client = createSandboxClient(logger, auth, region);
|
|
86
99
|
const started = Date.now();
|
|
87
100
|
|
|
101
|
+
// Detect if stdout/stderr are redirected to /dev/null
|
|
102
|
+
const stdoutIsNull = detectNullStream(1);
|
|
103
|
+
const stderrIsNull = detectNullStream(2);
|
|
104
|
+
|
|
105
|
+
// Build stream configuration
|
|
106
|
+
const streamConfig: {
|
|
107
|
+
timestamps?: boolean;
|
|
108
|
+
stdout?: string;
|
|
109
|
+
stderr?: string;
|
|
110
|
+
} = {
|
|
111
|
+
timestamps: opts.timestamps,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// --quiet: suppress all output streams (no server streams, no local capture)
|
|
115
|
+
if (opts.quiet) {
|
|
116
|
+
streamConfig.stdout = 'ignore';
|
|
117
|
+
streamConfig.stderr = 'ignore';
|
|
118
|
+
} else if (!options.json) {
|
|
119
|
+
// Auto-detect /dev/null redirection (only when not in JSON mode)
|
|
120
|
+
// In JSON mode we need output for the response, so keep streams even if redirected
|
|
121
|
+
if (stdoutIsNull) {
|
|
122
|
+
streamConfig.stdout = 'ignore';
|
|
123
|
+
}
|
|
124
|
+
if (stderrIsNull) {
|
|
125
|
+
streamConfig.stderr = 'ignore';
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
88
129
|
const abortController = new AbortController();
|
|
89
130
|
const handleSignal = () => {
|
|
90
131
|
abortController.abort();
|
|
@@ -100,7 +141,7 @@ export const execSubcommand = createCommand({
|
|
|
100
141
|
options: {
|
|
101
142
|
command: args.command,
|
|
102
143
|
timeout: opts.timeout,
|
|
103
|
-
stream:
|
|
144
|
+
stream: streamConfig,
|
|
104
145
|
},
|
|
105
146
|
orgId,
|
|
106
147
|
});
|
|
@@ -119,7 +160,7 @@ export const execSubcommand = createCommand({
|
|
|
119
160
|
const stdoutStreamUrl = execution.stdoutStreamUrl;
|
|
120
161
|
const stderrStreamUrl = execution.stderrStreamUrl;
|
|
121
162
|
const streamAbortController = new AbortController();
|
|
122
|
-
const streamPromises: Promise<
|
|
163
|
+
const streamPromises: Promise<{ bytesRead: number; chunks: number }>[] = [];
|
|
123
164
|
const streamLabels: string[] = [];
|
|
124
165
|
|
|
125
166
|
const isCombinedOutput =
|
|
@@ -135,27 +176,20 @@ export const execSubcommand = createCommand({
|
|
|
135
176
|
const stdoutChunks: string[] = [];
|
|
136
177
|
const stderrChunks: string[] = [];
|
|
137
178
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
outputChunks.push(chunk);
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
} else {
|
|
156
|
-
stdoutWritable = process.stdout;
|
|
157
|
-
stderrWritable = process.stderr;
|
|
158
|
-
}
|
|
179
|
+
const stdoutWritable: NodeJS.WritableStream =
|
|
180
|
+
options.json || stdoutIsNull
|
|
181
|
+
? createCaptureStream((chunk) => {
|
|
182
|
+
stdoutChunks.push(chunk);
|
|
183
|
+
outputChunks.push(chunk);
|
|
184
|
+
})
|
|
185
|
+
: process.stdout;
|
|
186
|
+
const stderrWritable: NodeJS.WritableStream =
|
|
187
|
+
options.json || stderrIsNull
|
|
188
|
+
? createCaptureStream((chunk) => {
|
|
189
|
+
stderrChunks.push(chunk);
|
|
190
|
+
outputChunks.push(chunk);
|
|
191
|
+
})
|
|
192
|
+
: process.stderr;
|
|
159
193
|
|
|
160
194
|
if (isCombinedOutput) {
|
|
161
195
|
logger.debug('[exec] starting combined stream: %s', stdoutStreamUrl);
|
|
@@ -166,7 +200,7 @@ export const execSubcommand = createCommand({
|
|
|
166
200
|
label: 'combined',
|
|
167
201
|
raw: true,
|
|
168
202
|
v2: true,
|
|
169
|
-
})
|
|
203
|
+
})
|
|
170
204
|
);
|
|
171
205
|
} else {
|
|
172
206
|
if (stdoutStreamUrl) {
|
|
@@ -178,7 +212,7 @@ export const execSubcommand = createCommand({
|
|
|
178
212
|
label: 'stdout',
|
|
179
213
|
raw: true,
|
|
180
214
|
v2: true,
|
|
181
|
-
})
|
|
215
|
+
})
|
|
182
216
|
);
|
|
183
217
|
}
|
|
184
218
|
|
|
@@ -191,7 +225,7 @@ export const execSubcommand = createCommand({
|
|
|
191
225
|
label: 'stderr',
|
|
192
226
|
raw: true,
|
|
193
227
|
v2: true,
|
|
194
|
-
})
|
|
228
|
+
})
|
|
195
229
|
);
|
|
196
230
|
}
|
|
197
231
|
}
|
|
@@ -203,13 +237,53 @@ export const execSubcommand = createCommand({
|
|
|
203
237
|
);
|
|
204
238
|
|
|
205
239
|
let finalExecution: Awaited<ReturnType<typeof executionGet>>;
|
|
240
|
+
let streamResults: { bytesRead: number; chunks: number }[] | undefined;
|
|
206
241
|
const pollStart = Date.now();
|
|
242
|
+
const executionWaitAbortController = new AbortController();
|
|
207
243
|
try {
|
|
208
|
-
|
|
244
|
+
const executionWaitPromise = executionGet(client, {
|
|
209
245
|
executionId: execution.executionId,
|
|
210
246
|
orgId,
|
|
211
247
|
wait: EXECUTION_WAIT_DURATION,
|
|
248
|
+
signal: executionWaitAbortController.signal,
|
|
212
249
|
});
|
|
250
|
+
|
|
251
|
+
if (streamPromises.length > 0) {
|
|
252
|
+
const winner = await Promise.race([
|
|
253
|
+
executionWaitPromise.then((result) => ({ type: 'execution' as const, result })),
|
|
254
|
+
Promise.all(streamPromises).then((results) => ({
|
|
255
|
+
type: 'streams' as const,
|
|
256
|
+
results,
|
|
257
|
+
})),
|
|
258
|
+
]);
|
|
259
|
+
|
|
260
|
+
if (winner.type === 'execution') {
|
|
261
|
+
finalExecution = winner.result;
|
|
262
|
+
} else {
|
|
263
|
+
streamResults = winner.results;
|
|
264
|
+
const bytesRead = streamResults.reduce(
|
|
265
|
+
(sum, result) => sum + result.bytesRead,
|
|
266
|
+
0
|
|
267
|
+
);
|
|
268
|
+
if (bytesRead === 0) {
|
|
269
|
+
logger.debug(
|
|
270
|
+
'[exec] all streams EOF with 0 bytes before executionGet completed — switching to fast terminal poll'
|
|
271
|
+
);
|
|
272
|
+
void executionWaitPromise.catch(() => undefined);
|
|
273
|
+
executionWaitAbortController.abort();
|
|
274
|
+
finalExecution = await waitForTerminalExecutionFast(
|
|
275
|
+
client,
|
|
276
|
+
execution.executionId,
|
|
277
|
+
orgId,
|
|
278
|
+
logger
|
|
279
|
+
);
|
|
280
|
+
} else {
|
|
281
|
+
finalExecution = await executionWaitPromise;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
} else {
|
|
285
|
+
finalExecution = await executionWaitPromise;
|
|
286
|
+
}
|
|
213
287
|
} catch (err) {
|
|
214
288
|
streamAbortController.abort();
|
|
215
289
|
throw err;
|
|
@@ -225,17 +299,21 @@ export const execSubcommand = createCommand({
|
|
|
225
299
|
logger.debug('[exec] waiting for %d stream(s) to EOF', streamPromises.length);
|
|
226
300
|
const streamWaitStart = Date.now();
|
|
227
301
|
let graceTriggered = false;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
302
|
+
if (!streamResults) {
|
|
303
|
+
const streamGraceMs = 500;
|
|
304
|
+
const streamGrace = setTimeout(() => {
|
|
305
|
+
graceTriggered = true;
|
|
306
|
+
logger.debug(
|
|
307
|
+
'[exec] stream grace period (%dms) expired after execution complete — aborting streams',
|
|
308
|
+
streamGraceMs
|
|
309
|
+
);
|
|
310
|
+
streamAbortController.abort();
|
|
311
|
+
}, streamGraceMs);
|
|
312
|
+
try {
|
|
313
|
+
streamResults = await Promise.all(streamPromises);
|
|
314
|
+
} finally {
|
|
315
|
+
clearTimeout(streamGrace);
|
|
316
|
+
}
|
|
239
317
|
}
|
|
240
318
|
logger.debug(
|
|
241
319
|
'[exec] all streams done in %dms (graceTriggered=%s)',
|
|
@@ -314,4 +392,41 @@ function createCaptureStream(onChunk: (chunk: string) => void): NodeJS.WritableS
|
|
|
314
392
|
});
|
|
315
393
|
}
|
|
316
394
|
|
|
395
|
+
const TERMINAL_EXECUTION_STATUSES = new Set([
|
|
396
|
+
'completed',
|
|
397
|
+
'failed',
|
|
398
|
+
'error',
|
|
399
|
+
'timeout',
|
|
400
|
+
'killed',
|
|
401
|
+
'cancelled',
|
|
402
|
+
]);
|
|
403
|
+
|
|
404
|
+
async function waitForTerminalExecutionFast(
|
|
405
|
+
client: Parameters<typeof executionGet>[0],
|
|
406
|
+
executionId: string,
|
|
407
|
+
orgId: string,
|
|
408
|
+
logger: Parameters<typeof streamUrlToWritable>[2]
|
|
409
|
+
) {
|
|
410
|
+
const deadline = Date.now() + EMPTY_STREAM_FAST_TIMEOUT_MS;
|
|
411
|
+
while (Date.now() < deadline) {
|
|
412
|
+
const info = await executionGet(client, { executionId, orgId });
|
|
413
|
+
if (TERMINAL_EXECUTION_STATUSES.has(info.status)) {
|
|
414
|
+
logger.debug(
|
|
415
|
+
'[exec] fast terminal poll observed status=%s for executionId=%s',
|
|
416
|
+
info.status,
|
|
417
|
+
executionId
|
|
418
|
+
);
|
|
419
|
+
return info;
|
|
420
|
+
}
|
|
421
|
+
await new Promise((resolve) => setTimeout(resolve, EMPTY_STREAM_FAST_POLL_MS));
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
logger.debug(
|
|
425
|
+
'[exec] fast terminal poll timed out after %dms for executionId=%s, falling back to long-poll',
|
|
426
|
+
EMPTY_STREAM_FAST_TIMEOUT_MS,
|
|
427
|
+
executionId
|
|
428
|
+
);
|
|
429
|
+
return executionGet(client, { executionId, orgId, wait: EXECUTION_WAIT_DURATION });
|
|
430
|
+
}
|
|
431
|
+
|
|
317
432
|
export default execSubcommand;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { executionList
|
|
1
|
+
import { executionList } from '@agentuity/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { getCommand } from '../../../../command-prefix';
|
|
4
4
|
import * as tui from '../../../../tui';
|
|
5
5
|
import { createCommand } from '../../../../types';
|
|
6
|
-
import { createSandboxClient } from '../util';
|
|
6
|
+
import { createSandboxClient, resolveSandboxTarget } from '../util';
|
|
7
7
|
|
|
8
8
|
const ExecutionInfoSchema = z.object({
|
|
9
9
|
executionId: z.string().describe('Execution ID'),
|
|
@@ -54,9 +54,14 @@ export const listSubcommand = createCommand({
|
|
|
54
54
|
async handler(ctx) {
|
|
55
55
|
const { args, opts, options, auth, logger, apiClient } = ctx;
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
const { region, orgId: resolvedOrgId } = await resolveSandboxTarget(
|
|
58
|
+
logger,
|
|
59
|
+
auth,
|
|
60
|
+
apiClient,
|
|
61
|
+
args.sandboxId,
|
|
62
|
+
ctx.config?.name ?? 'production',
|
|
63
|
+
ctx.config
|
|
64
|
+
);
|
|
60
65
|
const effectiveOrgId = opts?.orgId || resolvedOrgId;
|
|
61
66
|
const client = createSandboxClient(logger, auth, region);
|
|
62
67
|
|
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
readFileSync,
|
|
4
|
+
mkdirSync,
|
|
5
|
+
statSync,
|
|
6
|
+
readdirSync,
|
|
7
|
+
createWriteStream,
|
|
8
|
+
mkdtempSync,
|
|
9
|
+
rmSync,
|
|
10
|
+
} from 'node:fs';
|
|
3
11
|
import { dirname, resolve, basename, join, relative } from 'node:path';
|
|
12
|
+
import { tmpdir } from 'node:os';
|
|
13
|
+
import { pipeline } from 'node:stream/promises';
|
|
14
|
+
import { Readable } from 'node:stream';
|
|
15
|
+
import * as tar from 'tar';
|
|
4
16
|
import { createCommand } from '../../../../types';
|
|
5
17
|
import { toForwardSlash } from '../../../../utils/normalize-path';
|
|
6
18
|
import * as tui from '../../../../tui';
|
|
7
|
-
import { createSandboxClient } from '../util';
|
|
19
|
+
import { createSandboxClient, resolveSandboxTarget } from '../util';
|
|
8
20
|
import { getCommand } from '../../../../command-prefix';
|
|
9
21
|
import {
|
|
10
22
|
sandboxWriteFiles,
|
|
11
23
|
sandboxReadFile,
|
|
12
24
|
sandboxExecute,
|
|
13
25
|
executionGet,
|
|
14
|
-
|
|
26
|
+
sandboxDownloadArchive,
|
|
27
|
+
sandboxUploadArchive,
|
|
15
28
|
type APIClient,
|
|
16
29
|
} from '@agentuity/server';
|
|
17
30
|
import type { Logger, FileToWrite } from '@agentuity/core';
|
|
@@ -125,9 +138,14 @@ export const cpSubcommand = createCommand({
|
|
|
125
138
|
|
|
126
139
|
const sandboxId = source.sandboxId ?? destination.sandboxId!;
|
|
127
140
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
141
|
+
const { region, orgId } = await resolveSandboxTarget(
|
|
142
|
+
logger,
|
|
143
|
+
auth,
|
|
144
|
+
apiClient,
|
|
145
|
+
sandboxId,
|
|
146
|
+
ctx.config?.name ?? 'production',
|
|
147
|
+
ctx.config
|
|
148
|
+
);
|
|
131
149
|
|
|
132
150
|
const client = createSandboxClient(logger, auth, region);
|
|
133
151
|
const recursive = opts.recursive ?? false;
|
|
@@ -337,7 +355,6 @@ async function uploadDirectory(
|
|
|
337
355
|
logger.fatal(`Directory is empty: ${localDir}`);
|
|
338
356
|
}
|
|
339
357
|
|
|
340
|
-
const files: FileToWrite[] = [];
|
|
341
358
|
let totalBytes = 0;
|
|
342
359
|
const effectiveRemotePath = remotePath || basename(localDir);
|
|
343
360
|
const baseRemotePath = effectiveRemotePath.endsWith('/')
|
|
@@ -371,14 +388,23 @@ async function uploadDirectory(
|
|
|
371
388
|
}
|
|
372
389
|
|
|
373
390
|
for (const filePath of allFiles) {
|
|
374
|
-
|
|
375
|
-
const targetPath = `${baseRemotePath}/${relativePath}`;
|
|
376
|
-
const buffer = readFileSync(filePath);
|
|
377
|
-
files.push({ path: targetPath, content: buffer });
|
|
378
|
-
totalBytes += buffer.length;
|
|
391
|
+
totalBytes += statSync(filePath).size;
|
|
379
392
|
}
|
|
380
393
|
|
|
381
|
-
|
|
394
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'agentuity-fs-cp-'));
|
|
395
|
+
const archivePath = join(tempDir, 'upload.tar.gz');
|
|
396
|
+
try {
|
|
397
|
+
await createTarGzArchive(localDir, allFiles, archivePath);
|
|
398
|
+
await sandboxUploadArchive(client, {
|
|
399
|
+
sandboxId,
|
|
400
|
+
archive: Bun.file(archivePath).stream(),
|
|
401
|
+
path: baseRemotePath,
|
|
402
|
+
format: 'tar.gz',
|
|
403
|
+
orgId,
|
|
404
|
+
});
|
|
405
|
+
} finally {
|
|
406
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
407
|
+
}
|
|
382
408
|
|
|
383
409
|
if (!jsonOutput) {
|
|
384
410
|
tui.success(
|
|
@@ -386,7 +412,11 @@ async function uploadDirectory(
|
|
|
386
412
|
);
|
|
387
413
|
}
|
|
388
414
|
|
|
389
|
-
const implicitDirs = getImplicitDirectories(
|
|
415
|
+
const implicitDirs = getImplicitDirectories(
|
|
416
|
+
allFiles.map(
|
|
417
|
+
(filePath) => `${baseRemotePath}/${toForwardSlash(relative(localDir, filePath))}`
|
|
418
|
+
)
|
|
419
|
+
);
|
|
390
420
|
return {
|
|
391
421
|
source: localDir,
|
|
392
422
|
destination: `${sandboxId}:${baseRemotePath}`,
|
|
@@ -444,15 +474,6 @@ async function downloadSingleFile(
|
|
|
444
474
|
): Promise<z.infer<typeof SandboxCpResponseSchema>> {
|
|
445
475
|
const stream = await sandboxReadFile(client, { sandboxId, path: remotePath, orgId });
|
|
446
476
|
|
|
447
|
-
const chunks: Uint8Array[] = [];
|
|
448
|
-
const reader = stream.getReader();
|
|
449
|
-
while (true) {
|
|
450
|
-
const { done, value } = await reader.read();
|
|
451
|
-
if (done) break;
|
|
452
|
-
if (value) chunks.push(value);
|
|
453
|
-
}
|
|
454
|
-
const buffer = Buffer.concat(chunks);
|
|
455
|
-
|
|
456
477
|
let targetPath = localPath;
|
|
457
478
|
if (localPath.endsWith('/') || localPath === '.') {
|
|
458
479
|
targetPath = resolve(localPath, basename(remotePath));
|
|
@@ -462,101 +483,70 @@ async function downloadSingleFile(
|
|
|
462
483
|
|
|
463
484
|
const dir = dirname(targetPath);
|
|
464
485
|
mkdirSync(dir, { recursive: true });
|
|
465
|
-
|
|
466
|
-
|
|
486
|
+
await pipeline(
|
|
487
|
+
Readable.fromWeb(stream as unknown as globalThis.ReadableStream<ArrayBufferView>),
|
|
488
|
+
createWriteStream(targetPath)
|
|
489
|
+
);
|
|
490
|
+
const buffer = Bun.file(targetPath);
|
|
467
491
|
|
|
468
492
|
if (!jsonOutput) {
|
|
469
|
-
tui.success(`Copied ${sandboxId}:${remotePath} → ${targetPath} (${buffer.
|
|
493
|
+
tui.success(`Copied ${sandboxId}:${remotePath} → ${targetPath} (${buffer.size} bytes)`);
|
|
470
494
|
}
|
|
471
495
|
|
|
472
496
|
return {
|
|
473
497
|
source: `${sandboxId}:${remotePath}`,
|
|
474
498
|
destination: targetPath,
|
|
475
|
-
bytesTransferred: buffer.
|
|
499
|
+
bytesTransferred: buffer.size,
|
|
476
500
|
filesTransferred: 1,
|
|
477
501
|
};
|
|
478
502
|
}
|
|
479
503
|
|
|
480
504
|
async function downloadDirectory(
|
|
481
505
|
client: APIClient,
|
|
482
|
-
|
|
506
|
+
_logger: Logger,
|
|
483
507
|
orgId: string,
|
|
484
508
|
sandboxId: string,
|
|
485
509
|
remotePath: string,
|
|
486
510
|
localPath: string,
|
|
487
|
-
|
|
511
|
+
_timeout: string | undefined,
|
|
488
512
|
jsonOutput: boolean
|
|
489
513
|
): Promise<z.infer<typeof SandboxCpResponseSchema>> {
|
|
490
|
-
const listExecution = await sandboxExecute(client, {
|
|
491
|
-
sandboxId,
|
|
492
|
-
options: {
|
|
493
|
-
command: ['find', remotePath, '-type', 'f'],
|
|
494
|
-
timeout,
|
|
495
|
-
},
|
|
496
|
-
orgId,
|
|
497
|
-
});
|
|
498
|
-
|
|
499
|
-
const listChunks: Buffer[] = [];
|
|
500
|
-
if (listExecution.stdoutStreamUrl) {
|
|
501
|
-
await streamToBuffer(listExecution.stdoutStreamUrl, listChunks, logger);
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
await waitForExecution(client, orgId, listExecution.executionId, logger);
|
|
505
|
-
|
|
506
|
-
const fileList = Buffer.concat(listChunks)
|
|
507
|
-
.toString('utf-8')
|
|
508
|
-
.trim()
|
|
509
|
-
.split('\n')
|
|
510
|
-
.filter((f) => f.length > 0);
|
|
511
|
-
|
|
512
|
-
if (fileList.length === 0) {
|
|
513
|
-
logger.fatal(`No files found in directory: ${remotePath}`);
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
const baseRemotePath = remotePath.endsWith('/') ? remotePath.slice(0, -1) : remotePath;
|
|
517
514
|
const baseLocalPath = resolve(localPath);
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
mkdirSync(dir, { recursive: true });
|
|
541
|
-
writeFileSync(localFilePath, buffer);
|
|
542
|
-
|
|
543
|
-
if (!jsonOutput) {
|
|
544
|
-
logger.info(`Downloaded ${remoteFile} (${buffer.length} bytes)`);
|
|
545
|
-
}
|
|
546
|
-
} catch (err) {
|
|
547
|
-
logger.warn(`Failed to read file: ${remoteFile}, skipping: ${err}`);
|
|
548
|
-
continue;
|
|
549
|
-
}
|
|
515
|
+
mkdirSync(baseLocalPath, { recursive: true });
|
|
516
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'agentuity-fs-cp-'));
|
|
517
|
+
const archivePath = join(tempDir, 'download.tar.gz');
|
|
518
|
+
try {
|
|
519
|
+
const archiveStream = await sandboxDownloadArchive(client, {
|
|
520
|
+
sandboxId,
|
|
521
|
+
path: remotePath,
|
|
522
|
+
format: 'tar.gz',
|
|
523
|
+
orgId,
|
|
524
|
+
});
|
|
525
|
+
await pipeline(
|
|
526
|
+
Readable.fromWeb(archiveStream as unknown as globalThis.ReadableStream<ArrayBufferView>),
|
|
527
|
+
createWriteStream(archivePath)
|
|
528
|
+
);
|
|
529
|
+
await tar.extract({
|
|
530
|
+
file: archivePath,
|
|
531
|
+
cwd: baseLocalPath,
|
|
532
|
+
preservePaths: false,
|
|
533
|
+
strict: true,
|
|
534
|
+
});
|
|
535
|
+
} finally {
|
|
536
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
550
537
|
}
|
|
551
538
|
|
|
539
|
+
const fileList = getAllFiles(baseLocalPath);
|
|
540
|
+
const totalBytes = fileList.reduce((sum, filePath) => sum + statSync(filePath).size, 0);
|
|
541
|
+
|
|
552
542
|
if (!jsonOutput) {
|
|
553
543
|
tui.success(
|
|
554
|
-
`Copied ${sandboxId}:${
|
|
544
|
+
`Copied ${sandboxId}:${remotePath} → ${baseLocalPath} (${fileList.length} files, ${totalBytes} bytes)`
|
|
555
545
|
);
|
|
556
546
|
}
|
|
557
547
|
|
|
558
548
|
return {
|
|
559
|
-
source: `${sandboxId}:${
|
|
549
|
+
source: `${sandboxId}:${remotePath}`,
|
|
560
550
|
destination: baseLocalPath,
|
|
561
551
|
bytesTransferred: totalBytes,
|
|
562
552
|
filesTransferred: fileList.length,
|
|
@@ -601,42 +591,20 @@ async function waitForExecution(
|
|
|
601
591
|
logger.fatal('Execution timed out waiting for completion');
|
|
602
592
|
}
|
|
603
593
|
|
|
604
|
-
async function
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
continue;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
const reader = response.body.getReader();
|
|
622
|
-
|
|
623
|
-
while (true) {
|
|
624
|
-
const { done, value } = await reader.read();
|
|
625
|
-
if (done) {
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
if (value) {
|
|
630
|
-
chunks.push(Buffer.from(value));
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
} catch (err) {
|
|
634
|
-
if (err instanceof Error && err.name === 'AbortError') {
|
|
635
|
-
throw err;
|
|
636
|
-
}
|
|
637
|
-
logger.debug('stream error: %s', err);
|
|
638
|
-
}
|
|
639
|
-
}
|
|
594
|
+
async function createTarGzArchive(
|
|
595
|
+
localDir: string,
|
|
596
|
+
allFiles: string[],
|
|
597
|
+
archivePath: string
|
|
598
|
+
): Promise<void> {
|
|
599
|
+
const relativePaths = allFiles.map((filePath) => toForwardSlash(relative(localDir, filePath)));
|
|
600
|
+
await tar.create(
|
|
601
|
+
{
|
|
602
|
+
gzip: true,
|
|
603
|
+
file: archivePath,
|
|
604
|
+
cwd: localDir,
|
|
605
|
+
},
|
|
606
|
+
relativePaths
|
|
607
|
+
);
|
|
640
608
|
}
|
|
641
609
|
|
|
642
610
|
function sleep(ms: number): Promise<void> {
|