veryfront 0.1.277 → 0.1.279
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/esm/deno.js +1 -0
- package/esm/src/sandbox/lazy-sandbox.d.ts +4 -0
- package/esm/src/sandbox/lazy-sandbox.d.ts.map +1 -1
- package/esm/src/sandbox/lazy-sandbox.js +54 -16
- package/esm/src/sandbox/sandbox.d.ts +3 -1
- package/esm/src/sandbox/sandbox.d.ts.map +1 -1
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/deno.js +1 -0
- package/src/src/sandbox/lazy-sandbox.ts +60 -16
- package/src/src/sandbox/sandbox.ts +3 -1
- package/src/src/utils/version-constant.ts +1 -1
package/esm/deno.js
CHANGED
|
@@ -23,6 +23,7 @@ export declare class LazySandbox {
|
|
|
23
23
|
private heartbeatPromise;
|
|
24
24
|
private heartbeatTimer;
|
|
25
25
|
private lastHeartbeatAt;
|
|
26
|
+
private readonly activeCommandJobEndpoints;
|
|
26
27
|
constructor(options?: LazySandboxOptions);
|
|
27
28
|
ensure(): Promise<void>;
|
|
28
29
|
executeCommand(command: string, options?: ExecOptions): Promise<ExecResult>;
|
|
@@ -51,6 +52,9 @@ export declare class LazySandbox {
|
|
|
51
52
|
private requireEndpoint;
|
|
52
53
|
private resolveProjectId;
|
|
53
54
|
private resetSessionState;
|
|
55
|
+
private resolveExecOptions;
|
|
56
|
+
private resolveCommandJobEndpoint;
|
|
57
|
+
private updateTrackedCommandJob;
|
|
54
58
|
private authHeaders;
|
|
55
59
|
private jsonHeaders;
|
|
56
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lazy-sandbox.d.ts","sourceRoot":"","sources":["../../../src/src/sandbox/lazy-sandbox.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,gBAAgB,EAErB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,eAAe,EAGpB,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAaD,4EAA4E;AAC5E,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAC/D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,cAAc,CAAuD;IAC7E,OAAO,CAAC,eAAe,CAAK;
|
|
1
|
+
{"version":3,"file":"lazy-sandbox.d.ts","sourceRoot":"","sources":["../../../src/src/sandbox/lazy-sandbox.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,gBAAgB,EAErB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,eAAe,EAGpB,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAaD,4EAA4E;AAC5E,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAC/D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,cAAc,CAAuD;IAC7E,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAA6B;gBAE3D,OAAO,GAAE,kBAAuB;IAUtC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBvB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAsB1E,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,cAAc,CAAC,eAAe,CAAC;IAwCvF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcvC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB1E,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAqB5E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAkBjD,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyB7D,eAAe,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAkBxC,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAmBpD,SAAS,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA+CvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC5B,IAAI,EAAE,IAAI,MAAM,GAAG,IAAI,CAEtB;IAED,IAAI,GAAG,IAAI,MAAM,GAAG,IAAI,CAEvB;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;YAEa,gBAAgB;YAiChB,oBAAoB;YA2BpB,YAAY;IAc1B,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,iBAAiB;YAMX,aAAa;IAO3B,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,kBAAkB;YAKZ,yBAAyB;IAUvC,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;CAMpB"}
|
|
@@ -22,6 +22,7 @@ export class LazySandbox {
|
|
|
22
22
|
heartbeatPromise = null;
|
|
23
23
|
heartbeatTimer = null;
|
|
24
24
|
lastHeartbeatAt = 0;
|
|
25
|
+
activeCommandJobEndpoints = new Map();
|
|
25
26
|
constructor(options = {}) {
|
|
26
27
|
this.apiUrl = resolveSandboxApiUrl(options);
|
|
27
28
|
this.authToken = resolveSandboxAuthToken(options);
|
|
@@ -73,7 +74,7 @@ export class LazySandbox {
|
|
|
73
74
|
const res = await fetch(`${this.requireEndpoint()}/exec`, {
|
|
74
75
|
method: "POST",
|
|
75
76
|
headers: this.jsonHeaders(),
|
|
76
|
-
body: JSON.stringify({ command, ...options }),
|
|
77
|
+
body: JSON.stringify({ command, ...this.resolveExecOptions(options) }),
|
|
77
78
|
});
|
|
78
79
|
if (!res.ok) {
|
|
79
80
|
throw REQUEST_ERROR.create({ detail: `Exec failed: ${res.status} ${await res.text()}` });
|
|
@@ -126,21 +127,24 @@ export class LazySandbox {
|
|
|
126
127
|
}
|
|
127
128
|
async startCommandJob(command, options) {
|
|
128
129
|
await this.touchSession();
|
|
129
|
-
const
|
|
130
|
+
const endpoint = this.requireEndpoint();
|
|
131
|
+
const res = await fetch(`${endpoint}/exec/jobs`, {
|
|
130
132
|
method: "POST",
|
|
131
133
|
headers: this.jsonHeaders(),
|
|
132
|
-
body: JSON.stringify({ command, ...options }),
|
|
134
|
+
body: JSON.stringify({ command, ...this.resolveExecOptions(options) }),
|
|
133
135
|
});
|
|
134
136
|
if (!res.ok) {
|
|
135
137
|
throw REQUEST_ERROR.create({
|
|
136
138
|
detail: `Start command job failed: ${res.status} ${await res.text()}`,
|
|
137
139
|
});
|
|
138
140
|
}
|
|
139
|
-
|
|
141
|
+
const job = mapCommandJob(await res.json());
|
|
142
|
+
this.updateTrackedCommandJob(job, endpoint);
|
|
143
|
+
return job;
|
|
140
144
|
}
|
|
141
145
|
async getCommandJob(jobId) {
|
|
142
|
-
await this.
|
|
143
|
-
const res = await fetch(`${
|
|
146
|
+
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
147
|
+
const res = await fetch(`${endpoint}/exec/jobs/${jobId}`, {
|
|
144
148
|
headers: this.authHeaders(),
|
|
145
149
|
});
|
|
146
150
|
if (!res.ok) {
|
|
@@ -148,11 +152,13 @@ export class LazySandbox {
|
|
|
148
152
|
detail: `Get command job failed: ${res.status} ${await res.text()}`,
|
|
149
153
|
});
|
|
150
154
|
}
|
|
151
|
-
|
|
155
|
+
const job = mapCommandJob(await res.json());
|
|
156
|
+
this.updateTrackedCommandJob(job, endpoint);
|
|
157
|
+
return job;
|
|
152
158
|
}
|
|
153
159
|
async getCommandJobOutput(jobId) {
|
|
154
|
-
await this.
|
|
155
|
-
const res = await fetch(`${
|
|
160
|
+
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
161
|
+
const res = await fetch(`${endpoint}/exec/jobs/${jobId}/output`, {
|
|
156
162
|
headers: this.authHeaders(),
|
|
157
163
|
});
|
|
158
164
|
if (!res.ok) {
|
|
@@ -161,13 +167,15 @@ export class LazySandbox {
|
|
|
161
167
|
});
|
|
162
168
|
}
|
|
163
169
|
const json = await res.json();
|
|
164
|
-
|
|
170
|
+
const output = {
|
|
165
171
|
...mapCommandJob(json),
|
|
166
172
|
stdout: json.stdout,
|
|
167
173
|
stderr: json.stderr,
|
|
168
174
|
stdoutTruncated: json.stdout_truncated,
|
|
169
175
|
stderrTruncated: json.stderr_truncated,
|
|
170
176
|
};
|
|
177
|
+
this.updateTrackedCommandJob(output, endpoint);
|
|
178
|
+
return output;
|
|
171
179
|
}
|
|
172
180
|
async listCommandJobs() {
|
|
173
181
|
await this.ensure();
|
|
@@ -184,8 +192,8 @@ export class LazySandbox {
|
|
|
184
192
|
return jobs.map((job) => mapCommandJob(job));
|
|
185
193
|
}
|
|
186
194
|
async cancelCommandJob(jobId) {
|
|
187
|
-
await this.
|
|
188
|
-
const res = await fetch(`${
|
|
195
|
+
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
196
|
+
const res = await fetch(`${endpoint}/exec/jobs/${jobId}/cancel`, {
|
|
189
197
|
method: "POST",
|
|
190
198
|
headers: this.authHeaders(),
|
|
191
199
|
});
|
|
@@ -194,7 +202,9 @@ export class LazySandbox {
|
|
|
194
202
|
detail: `Cancel command job failed: ${res.status} ${await res.text()}`,
|
|
195
203
|
});
|
|
196
204
|
}
|
|
197
|
-
|
|
205
|
+
const job = mapCommandJob(await res.json());
|
|
206
|
+
this.updateTrackedCommandJob(job, endpoint);
|
|
207
|
+
return job;
|
|
198
208
|
}
|
|
199
209
|
async heartbeat(force = false) {
|
|
200
210
|
const currentSessionId = this.sessionId;
|
|
@@ -215,8 +225,10 @@ export class LazySandbox {
|
|
|
215
225
|
});
|
|
216
226
|
if (!res.ok) {
|
|
217
227
|
if (this.sessionId === currentSessionId) {
|
|
218
|
-
|
|
219
|
-
|
|
228
|
+
if (this.activeCommandJobEndpoints.size === 0) {
|
|
229
|
+
await this.deleteSession(currentSessionId);
|
|
230
|
+
this.resetSessionState(currentSessionId);
|
|
231
|
+
}
|
|
220
232
|
}
|
|
221
233
|
throw new Error(`Sandbox heartbeat failed: ${res.status} ${await res.text()}`);
|
|
222
234
|
}
|
|
@@ -338,7 +350,7 @@ export class LazySandbox {
|
|
|
338
350
|
await this.heartbeat();
|
|
339
351
|
}
|
|
340
352
|
startHeartbeatLoop() {
|
|
341
|
-
if (!this.sessionId || this.heartbeatTimer)
|
|
353
|
+
if (!this.sessionId || this.heartbeatTimer || this.activeCommandJobEndpoints.size > 0)
|
|
342
354
|
return;
|
|
343
355
|
this.heartbeatTimer = dntShim.setInterval(() => {
|
|
344
356
|
void this.heartbeat().catch(() => {
|
|
@@ -370,6 +382,7 @@ export class LazySandbox {
|
|
|
370
382
|
resetSessionState(sessionId) {
|
|
371
383
|
if (!sessionId || this.sessionId === sessionId) {
|
|
372
384
|
this.stopHeartbeatLoop();
|
|
385
|
+
this.activeCommandJobEndpoints.clear();
|
|
373
386
|
this.endpoint = null;
|
|
374
387
|
this.sessionId = null;
|
|
375
388
|
this.sessionProjectId = null;
|
|
@@ -377,6 +390,31 @@ export class LazySandbox {
|
|
|
377
390
|
this.lastHeartbeatAt = 0;
|
|
378
391
|
}
|
|
379
392
|
}
|
|
393
|
+
resolveExecOptions(options) {
|
|
394
|
+
const projectReference = options?.projectReference ?? this.resolveProjectId() ?? undefined;
|
|
395
|
+
return projectReference ? { ...options, projectReference } : options;
|
|
396
|
+
}
|
|
397
|
+
async resolveCommandJobEndpoint(jobId) {
|
|
398
|
+
const trackedEndpoint = this.activeCommandJobEndpoints.get(jobId);
|
|
399
|
+
if (trackedEndpoint) {
|
|
400
|
+
return trackedEndpoint;
|
|
401
|
+
}
|
|
402
|
+
await this.ensure();
|
|
403
|
+
return this.requireEndpoint();
|
|
404
|
+
}
|
|
405
|
+
updateTrackedCommandJob(job, endpoint) {
|
|
406
|
+
if (job.status === "running") {
|
|
407
|
+
this.activeCommandJobEndpoints.set(job.id, endpoint);
|
|
408
|
+
this.stopHeartbeatLoop();
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
if (!this.activeCommandJobEndpoints.delete(job.id)) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (this.activeCommandJobEndpoints.size === 0 && this.endpoint) {
|
|
415
|
+
this.startHeartbeatLoop();
|
|
416
|
+
}
|
|
417
|
+
}
|
|
380
418
|
authHeaders() {
|
|
381
419
|
return { Authorization: `Bearer ${this.authToken}` };
|
|
382
420
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LazySandbox, type LazySandboxOptions } from "./lazy-sandbox.js";
|
|
2
|
-
/** Options for command execution: working directory, timeout, and
|
|
2
|
+
/** Options for command execution: working directory, timeout, environment variables, and optional project reference. */
|
|
3
3
|
export interface ExecOptions {
|
|
4
4
|
/** Working directory for the command. */
|
|
5
5
|
cwd?: string;
|
|
@@ -7,6 +7,8 @@ export interface ExecOptions {
|
|
|
7
7
|
timeout_seconds?: number;
|
|
8
8
|
/** Additional environment variables for the command. */
|
|
9
9
|
env?: Record<string, string>;
|
|
10
|
+
/** Optional project reference forwarded to sandbox command surfaces that support project-scoped execution. */
|
|
11
|
+
projectReference?: string;
|
|
10
12
|
}
|
|
11
13
|
/** Options for creating a sandbox session. */
|
|
12
14
|
export interface SandboxOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../../src/src/sandbox/sandbox.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../../src/src/sandbox/sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.
|
|
1
|
+
export declare const VERSION = "0.1.279";
|
|
2
2
|
//# sourceMappingURL=version-constant.d.ts.map
|
package/package.json
CHANGED
package/src/deno.js
CHANGED
|
@@ -50,6 +50,7 @@ export class LazySandbox {
|
|
|
50
50
|
private heartbeatPromise: Promise<void> | null = null;
|
|
51
51
|
private heartbeatTimer: ReturnType<typeof dntShim.setInterval> | null = null;
|
|
52
52
|
private lastHeartbeatAt = 0;
|
|
53
|
+
private readonly activeCommandJobEndpoints = new Map<string, string>();
|
|
53
54
|
|
|
54
55
|
constructor(options: LazySandboxOptions = {}) {
|
|
55
56
|
this.apiUrl = resolveSandboxApiUrl(options);
|
|
@@ -108,7 +109,7 @@ export class LazySandbox {
|
|
|
108
109
|
const res = await fetch(`${this.requireEndpoint()}/exec`, {
|
|
109
110
|
method: "POST",
|
|
110
111
|
headers: this.jsonHeaders(),
|
|
111
|
-
body: JSON.stringify({ command, ...options }),
|
|
112
|
+
body: JSON.stringify({ command, ...this.resolveExecOptions(options) }),
|
|
112
113
|
});
|
|
113
114
|
|
|
114
115
|
if (!res.ok) {
|
|
@@ -174,11 +175,12 @@ export class LazySandbox {
|
|
|
174
175
|
|
|
175
176
|
async startCommandJob(command: string, options?: ExecOptions): Promise<CommandJob> {
|
|
176
177
|
await this.touchSession();
|
|
178
|
+
const endpoint = this.requireEndpoint();
|
|
177
179
|
|
|
178
|
-
const res = await fetch(`${
|
|
180
|
+
const res = await fetch(`${endpoint}/exec/jobs`, {
|
|
179
181
|
method: "POST",
|
|
180
182
|
headers: this.jsonHeaders(),
|
|
181
|
-
body: JSON.stringify({ command, ...options }),
|
|
183
|
+
body: JSON.stringify({ command, ...this.resolveExecOptions(options) }),
|
|
182
184
|
});
|
|
183
185
|
|
|
184
186
|
if (!res.ok) {
|
|
@@ -187,13 +189,15 @@ export class LazySandbox {
|
|
|
187
189
|
});
|
|
188
190
|
}
|
|
189
191
|
|
|
190
|
-
|
|
192
|
+
const job = mapCommandJob(await res.json());
|
|
193
|
+
this.updateTrackedCommandJob(job, endpoint);
|
|
194
|
+
return job;
|
|
191
195
|
}
|
|
192
196
|
|
|
193
197
|
async getCommandJob(jobId: string): Promise<CommandJob> {
|
|
194
|
-
await this.
|
|
198
|
+
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
195
199
|
|
|
196
|
-
const res = await fetch(`${
|
|
200
|
+
const res = await fetch(`${endpoint}/exec/jobs/${jobId}`, {
|
|
197
201
|
headers: this.authHeaders(),
|
|
198
202
|
});
|
|
199
203
|
|
|
@@ -203,13 +207,15 @@ export class LazySandbox {
|
|
|
203
207
|
});
|
|
204
208
|
}
|
|
205
209
|
|
|
206
|
-
|
|
210
|
+
const job = mapCommandJob(await res.json());
|
|
211
|
+
this.updateTrackedCommandJob(job, endpoint);
|
|
212
|
+
return job;
|
|
207
213
|
}
|
|
208
214
|
|
|
209
215
|
async getCommandJobOutput(jobId: string): Promise<CommandJobOutput> {
|
|
210
|
-
await this.
|
|
216
|
+
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
211
217
|
|
|
212
|
-
const res = await fetch(`${
|
|
218
|
+
const res = await fetch(`${endpoint}/exec/jobs/${jobId}/output`, {
|
|
213
219
|
headers: this.authHeaders(),
|
|
214
220
|
});
|
|
215
221
|
|
|
@@ -220,13 +226,15 @@ export class LazySandbox {
|
|
|
220
226
|
}
|
|
221
227
|
|
|
222
228
|
const json = await res.json();
|
|
223
|
-
|
|
229
|
+
const output = {
|
|
224
230
|
...mapCommandJob(json),
|
|
225
231
|
stdout: json.stdout,
|
|
226
232
|
stderr: json.stderr,
|
|
227
233
|
stdoutTruncated: json.stdout_truncated,
|
|
228
234
|
stderrTruncated: json.stderr_truncated,
|
|
229
235
|
};
|
|
236
|
+
this.updateTrackedCommandJob(output, endpoint);
|
|
237
|
+
return output;
|
|
230
238
|
}
|
|
231
239
|
|
|
232
240
|
async listCommandJobs(): Promise<CommandJob[]> {
|
|
@@ -248,9 +256,9 @@ export class LazySandbox {
|
|
|
248
256
|
}
|
|
249
257
|
|
|
250
258
|
async cancelCommandJob(jobId: string): Promise<CommandJob> {
|
|
251
|
-
await this.
|
|
259
|
+
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
252
260
|
|
|
253
|
-
const res = await fetch(`${
|
|
261
|
+
const res = await fetch(`${endpoint}/exec/jobs/${jobId}/cancel`, {
|
|
254
262
|
method: "POST",
|
|
255
263
|
headers: this.authHeaders(),
|
|
256
264
|
});
|
|
@@ -261,7 +269,9 @@ export class LazySandbox {
|
|
|
261
269
|
});
|
|
262
270
|
}
|
|
263
271
|
|
|
264
|
-
|
|
272
|
+
const job = mapCommandJob(await res.json());
|
|
273
|
+
this.updateTrackedCommandJob(job, endpoint);
|
|
274
|
+
return job;
|
|
265
275
|
}
|
|
266
276
|
|
|
267
277
|
async heartbeat(force = false): Promise<void> {
|
|
@@ -288,8 +298,10 @@ export class LazySandbox {
|
|
|
288
298
|
|
|
289
299
|
if (!res.ok) {
|
|
290
300
|
if (this.sessionId === currentSessionId) {
|
|
291
|
-
|
|
292
|
-
|
|
301
|
+
if (this.activeCommandJobEndpoints.size === 0) {
|
|
302
|
+
await this.deleteSession(currentSessionId);
|
|
303
|
+
this.resetSessionState(currentSessionId);
|
|
304
|
+
}
|
|
293
305
|
}
|
|
294
306
|
|
|
295
307
|
throw new Error(`Sandbox heartbeat failed: ${res.status} ${await res.text()}`);
|
|
@@ -432,7 +444,7 @@ export class LazySandbox {
|
|
|
432
444
|
}
|
|
433
445
|
|
|
434
446
|
private startHeartbeatLoop(): void {
|
|
435
|
-
if (!this.sessionId || this.heartbeatTimer) return;
|
|
447
|
+
if (!this.sessionId || this.heartbeatTimer || this.activeCommandJobEndpoints.size > 0) return;
|
|
436
448
|
|
|
437
449
|
this.heartbeatTimer = dntShim.setInterval(() => {
|
|
438
450
|
void this.heartbeat().catch(() => {
|
|
@@ -468,6 +480,7 @@ export class LazySandbox {
|
|
|
468
480
|
private resetSessionState(sessionId?: string): void {
|
|
469
481
|
if (!sessionId || this.sessionId === sessionId) {
|
|
470
482
|
this.stopHeartbeatLoop();
|
|
483
|
+
this.activeCommandJobEndpoints.clear();
|
|
471
484
|
this.endpoint = null;
|
|
472
485
|
this.sessionId = null;
|
|
473
486
|
this.sessionProjectId = null;
|
|
@@ -476,6 +489,37 @@ export class LazySandbox {
|
|
|
476
489
|
}
|
|
477
490
|
}
|
|
478
491
|
|
|
492
|
+
private resolveExecOptions(options?: ExecOptions): ExecOptions | undefined {
|
|
493
|
+
const projectReference = options?.projectReference ?? this.resolveProjectId() ?? undefined;
|
|
494
|
+
return projectReference ? { ...options, projectReference } : options;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
private async resolveCommandJobEndpoint(jobId: string): Promise<string> {
|
|
498
|
+
const trackedEndpoint = this.activeCommandJobEndpoints.get(jobId);
|
|
499
|
+
if (trackedEndpoint) {
|
|
500
|
+
return trackedEndpoint;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
await this.ensure();
|
|
504
|
+
return this.requireEndpoint();
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
private updateTrackedCommandJob(job: Pick<CommandJob, "id" | "status">, endpoint: string): void {
|
|
508
|
+
if (job.status === "running") {
|
|
509
|
+
this.activeCommandJobEndpoints.set(job.id, endpoint);
|
|
510
|
+
this.stopHeartbeatLoop();
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
if (!this.activeCommandJobEndpoints.delete(job.id)) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if (this.activeCommandJobEndpoints.size === 0 && this.endpoint) {
|
|
519
|
+
this.startHeartbeatLoop();
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
479
523
|
private authHeaders(): HeadersInit {
|
|
480
524
|
return { Authorization: `Bearer ${this.authToken}` };
|
|
481
525
|
}
|
|
@@ -20,7 +20,7 @@ import { getVeryfrontCloudAuthToken } from "../platform/cloud/resolver.js";
|
|
|
20
20
|
import { getHostEnv } from "../platform/compat/process.js";
|
|
21
21
|
import { LazySandbox, type LazySandboxOptions } from "./lazy-sandbox.js";
|
|
22
22
|
|
|
23
|
-
/** Options for command execution: working directory, timeout, and
|
|
23
|
+
/** Options for command execution: working directory, timeout, environment variables, and optional project reference. */
|
|
24
24
|
export interface ExecOptions {
|
|
25
25
|
/** Working directory for the command. */
|
|
26
26
|
cwd?: string;
|
|
@@ -28,6 +28,8 @@ export interface ExecOptions {
|
|
|
28
28
|
timeout_seconds?: number;
|
|
29
29
|
/** Additional environment variables for the command. */
|
|
30
30
|
env?: Record<string, string>;
|
|
31
|
+
/** Optional project reference forwarded to sandbox command surfaces that support project-scoped execution. */
|
|
32
|
+
projectReference?: string;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
/** Options for creating a sandbox session. */
|