@electric-agent/studio 1.0.0

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 (104) hide show
  1. package/dist/bridge/daytona.d.ts +35 -0
  2. package/dist/bridge/daytona.d.ts.map +1 -0
  3. package/dist/bridge/daytona.js +146 -0
  4. package/dist/bridge/daytona.js.map +1 -0
  5. package/dist/bridge/docker-stdio.d.ts +30 -0
  6. package/dist/bridge/docker-stdio.d.ts.map +1 -0
  7. package/dist/bridge/docker-stdio.js +141 -0
  8. package/dist/bridge/docker-stdio.js.map +1 -0
  9. package/dist/bridge/hosted.d.ts +28 -0
  10. package/dist/bridge/hosted.d.ts.map +1 -0
  11. package/dist/bridge/hosted.js +113 -0
  12. package/dist/bridge/hosted.js.map +1 -0
  13. package/dist/bridge/index.d.ts +6 -0
  14. package/dist/bridge/index.d.ts.map +1 -0
  15. package/dist/bridge/index.js +5 -0
  16. package/dist/bridge/index.js.map +1 -0
  17. package/dist/bridge/sprites.d.ts +32 -0
  18. package/dist/bridge/sprites.d.ts.map +1 -0
  19. package/dist/bridge/sprites.js +138 -0
  20. package/dist/bridge/sprites.js.map +1 -0
  21. package/dist/bridge/types.d.ts +97 -0
  22. package/dist/bridge/types.d.ts.map +1 -0
  23. package/dist/bridge/types.js +2 -0
  24. package/dist/bridge/types.js.map +1 -0
  25. package/dist/client/assets/OpenSauceOne-Bold-BeiFYFR5.woff2 +0 -0
  26. package/dist/client/assets/OpenSauceOne-ExtraBold-DO6BqiNe.woff2 +0 -0
  27. package/dist/client/assets/OpenSauceOne-Light-NEdTeQp-.woff2 +0 -0
  28. package/dist/client/assets/OpenSauceOne-Medium-Cu5cjAHY.woff2 +0 -0
  29. package/dist/client/assets/OpenSauceOne-Regular-BivIUdzJ.woff2 +0 -0
  30. package/dist/client/assets/SourceCodePro-Regular-CoIbWt_c.woff2 +0 -0
  31. package/dist/client/assets/index-CK__1-6e.css +1 -0
  32. package/dist/client/assets/index-DKL-jl7t.js +241 -0
  33. package/dist/client/favicon.ico +0 -0
  34. package/dist/client/img/brand/favicon.png +0 -0
  35. package/dist/client/img/brand/favicon.svg +4 -0
  36. package/dist/client/img/brand/icon.svg +4 -0
  37. package/dist/client/img/brand/logo.inverse.svg +13 -0
  38. package/dist/client/img/brand/logo.svg +13 -0
  39. package/dist/client/index.html +16 -0
  40. package/dist/electric-api.d.ts +14 -0
  41. package/dist/electric-api.d.ts.map +1 -0
  42. package/dist/electric-api.js +70 -0
  43. package/dist/electric-api.js.map +1 -0
  44. package/dist/gate.d.ts +28 -0
  45. package/dist/gate.d.ts.map +1 -0
  46. package/dist/gate.js +72 -0
  47. package/dist/gate.js.map +1 -0
  48. package/dist/git.d.ts +30 -0
  49. package/dist/git.d.ts.map +1 -0
  50. package/dist/git.js +115 -0
  51. package/dist/git.js.map +1 -0
  52. package/dist/index.d.ts +8 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +6 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/project-utils.d.ts +9 -0
  57. package/dist/project-utils.d.ts.map +1 -0
  58. package/dist/project-utils.js +17 -0
  59. package/dist/project-utils.js.map +1 -0
  60. package/dist/sandbox/daytona-push.d.ts +3 -0
  61. package/dist/sandbox/daytona-push.d.ts.map +1 -0
  62. package/dist/sandbox/daytona-push.js +56 -0
  63. package/dist/sandbox/daytona-push.js.map +1 -0
  64. package/dist/sandbox/daytona-registry.d.ts +41 -0
  65. package/dist/sandbox/daytona-registry.d.ts.map +1 -0
  66. package/dist/sandbox/daytona-registry.js +127 -0
  67. package/dist/sandbox/daytona-registry.js.map +1 -0
  68. package/dist/sandbox/daytona.d.ts +41 -0
  69. package/dist/sandbox/daytona.d.ts.map +1 -0
  70. package/dist/sandbox/daytona.js +282 -0
  71. package/dist/sandbox/daytona.js.map +1 -0
  72. package/dist/sandbox/docker.d.ts +29 -0
  73. package/dist/sandbox/docker.d.ts.map +1 -0
  74. package/dist/sandbox/docker.js +465 -0
  75. package/dist/sandbox/docker.js.map +1 -0
  76. package/dist/sandbox/index.d.ts +5 -0
  77. package/dist/sandbox/index.d.ts.map +1 -0
  78. package/dist/sandbox/index.js +4 -0
  79. package/dist/sandbox/index.js.map +1 -0
  80. package/dist/sandbox/sprites-bootstrap.d.ts +26 -0
  81. package/dist/sandbox/sprites-bootstrap.d.ts.map +1 -0
  82. package/dist/sandbox/sprites-bootstrap.js +127 -0
  83. package/dist/sandbox/sprites-bootstrap.js.map +1 -0
  84. package/dist/sandbox/sprites.d.ts +55 -0
  85. package/dist/sandbox/sprites.d.ts.map +1 -0
  86. package/dist/sandbox/sprites.js +323 -0
  87. package/dist/sandbox/sprites.js.map +1 -0
  88. package/dist/sandbox/types.d.ts +73 -0
  89. package/dist/sandbox/types.d.ts.map +1 -0
  90. package/dist/sandbox/types.js +5 -0
  91. package/dist/sandbox/types.js.map +1 -0
  92. package/dist/server.d.ts +26 -0
  93. package/dist/server.d.ts.map +1 -0
  94. package/dist/server.js +1266 -0
  95. package/dist/server.js.map +1 -0
  96. package/dist/sessions.d.ts +46 -0
  97. package/dist/sessions.d.ts.map +1 -0
  98. package/dist/sessions.js +66 -0
  99. package/dist/sessions.js.map +1 -0
  100. package/dist/streams.d.ts +34 -0
  101. package/dist/streams.d.ts.map +1 -0
  102. package/dist/streams.js +42 -0
  103. package/dist/streams.js.map +1 -0
  104. package/package.json +84 -0
@@ -0,0 +1,465 @@
1
+ import { execFileSync, execSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import net from "node:net";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ // ---------------------------------------------------------------------------
7
+ // Constants
8
+ // ---------------------------------------------------------------------------
9
+ const SANDBOX_IMAGE = "electric-agent-sandbox";
10
+ // ---------------------------------------------------------------------------
11
+ // Internal helpers
12
+ // ---------------------------------------------------------------------------
13
+ function findFreePort() {
14
+ return new Promise((resolve, reject) => {
15
+ const server = net.createServer();
16
+ server.listen(0, "127.0.0.1", () => {
17
+ const addr = server.address();
18
+ if (addr && typeof addr === "object") {
19
+ const port = addr.port;
20
+ server.close(() => resolve(port));
21
+ }
22
+ else {
23
+ server.close(() => reject(new Error("Could not determine free port")));
24
+ }
25
+ });
26
+ server.on("error", reject);
27
+ });
28
+ }
29
+ function resolveAuthEnv(opts) {
30
+ if (opts?.apiKey)
31
+ return ["ANTHROPIC_API_KEY", opts.apiKey];
32
+ if (opts?.oauthToken)
33
+ return ["CLAUDE_CODE_OAUTH_TOKEN", opts.oauthToken];
34
+ return null;
35
+ }
36
+ function generateComposeFile(port, auth, infra = { mode: "local" }, streamEnv = {}, deferAgentStart = false, ghToken) {
37
+ const isCloud = infra.mode === "cloud";
38
+ const agentEnv = [
39
+ `DATABASE_URL=${isCloud ? infra.databaseUrl : "postgresql://postgres:password@postgres:5432/electric"}`,
40
+ `ELECTRIC_URL=${isCloud ? infra.electricUrl : "http://electric:3000"}`,
41
+ "VITE_PORT=5173",
42
+ "SANDBOX_MODE=1",
43
+ ];
44
+ if (isCloud) {
45
+ agentEnv.push(`ELECTRIC_SOURCE_ID=${infra.sourceId}`);
46
+ agentEnv.push(`ELECTRIC_SECRET=${infra.secret}`);
47
+ }
48
+ if (auth) {
49
+ agentEnv.push(`${auth[0]}=${auth[1]}`);
50
+ }
51
+ if (ghToken) {
52
+ agentEnv.push(`GH_TOKEN=${ghToken}`);
53
+ }
54
+ // Add stream env vars for hosted Durable Streams communication
55
+ for (const [key, value] of Object.entries(streamEnv)) {
56
+ agentEnv.push(`${key}=${value}`);
57
+ }
58
+ const agentEnvYaml = agentEnv.map((e) => ` - ${e}`).join("\n");
59
+ // When deferAgentStart is true, keep the container alive without starting the agent.
60
+ // The bridge will start the agent via `docker exec -i`.
61
+ const agentCommand = deferAgentStart
62
+ ? '["tail", "-f", "/dev/null"]'
63
+ : '["electric-agent", "headless"]';
64
+ if (isCloud) {
65
+ return `services:
66
+ agent:
67
+ image: ${SANDBOX_IMAGE}
68
+ ports:
69
+ - "${port}:5173"
70
+ environment:
71
+ ${agentEnvYaml}
72
+ volumes:
73
+ - workspace:/home/agent/workspace
74
+ stdin_open: true
75
+ command: ${agentCommand}
76
+
77
+ volumes:
78
+ workspace:
79
+ `;
80
+ }
81
+ return `services:
82
+ postgres:
83
+ image: postgres:17
84
+ environment:
85
+ POSTGRES_DB: electric
86
+ POSTGRES_USER: postgres
87
+ POSTGRES_PASSWORD: password
88
+ command: postgres -c wal_level=logical -c max_replication_slots=10 -c max_wal_senders=10
89
+ healthcheck:
90
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
91
+ interval: 2s
92
+ timeout: 5s
93
+ retries: 10
94
+
95
+ electric:
96
+ image: electricsql/electric:latest
97
+ environment:
98
+ DATABASE_URL: postgresql://postgres:password@postgres:5432/electric
99
+ ELECTRIC_INSECURE: "true"
100
+ depends_on:
101
+ postgres:
102
+ condition: service_healthy
103
+
104
+ agent:
105
+ image: ${SANDBOX_IMAGE}
106
+ ports:
107
+ - "${port}:5173"
108
+ environment:
109
+ ${agentEnvYaml}
110
+ volumes:
111
+ - workspace:/home/agent/workspace
112
+ depends_on:
113
+ electric:
114
+ condition: service_started
115
+ stdin_open: true
116
+ command: ${agentCommand}
117
+
118
+ volumes:
119
+ workspace:
120
+ `;
121
+ }
122
+ async function waitForElectric(project, composePath) {
123
+ const start = Date.now();
124
+ while (Date.now() - start < 60_000) {
125
+ try {
126
+ execSync(`docker compose -p ${project} -f ${composePath} exec -T electric curl -sf http://localhost:3000/v1/health`, { stdio: "ignore", timeout: 3000 });
127
+ return;
128
+ }
129
+ catch {
130
+ // Not ready yet
131
+ }
132
+ await new Promise((r) => setTimeout(r, 1000));
133
+ }
134
+ throw new Error("Electric did not become healthy in time");
135
+ }
136
+ function getAgentContainerId(state) {
137
+ try {
138
+ const composePath = path.join(state.composeDir, "docker-compose.yml");
139
+ const id = execFileSync("docker", ["compose", "-p", state.composeProject, "-f", composePath, "ps", "-q", "agent"], { encoding: "utf-8", timeout: 5000, stdio: ["ignore", "pipe", "ignore"] }).trim();
140
+ return id || null;
141
+ }
142
+ catch {
143
+ return null;
144
+ }
145
+ }
146
+ function execInContainer(state, command, opts) {
147
+ const containerId = getAgentContainerId(state);
148
+ if (!containerId)
149
+ throw new Error("No running container");
150
+ return execFileSync("docker", ["exec", containerId, "sh", "-c", command], {
151
+ encoding: "utf-8",
152
+ timeout: opts?.timeout ?? 30_000,
153
+ stdio: ["ignore", "pipe", "pipe"],
154
+ });
155
+ }
156
+ // ---------------------------------------------------------------------------
157
+ // DockerSandboxProvider
158
+ // ---------------------------------------------------------------------------
159
+ export class DockerSandboxProvider {
160
+ runtime = "docker";
161
+ activeContainers = new Map();
162
+ internalState = new Map();
163
+ getState(handle) {
164
+ const state = this.internalState.get(handle.sessionId);
165
+ if (!state)
166
+ throw new Error(`No internal state for session ${handle.sessionId}`);
167
+ return state;
168
+ }
169
+ async create(sessionId, opts) {
170
+ const port = await findFreePort();
171
+ const slug = (opts?.projectName || sessionId.slice(0, 8))
172
+ .replace(/[^a-z0-9-]/gi, "-")
173
+ .toLowerCase();
174
+ const project = `ea-${slug}`;
175
+ const infra = opts?.infra ?? { mode: "local" };
176
+ console.log(`[docker] Creating sandbox: session=${sessionId} project=${project} port=${port} infra=${infra.mode}`);
177
+ const composeDir = fs.mkdtempSync(path.join(os.tmpdir(), `${project}-`));
178
+ const composePath = path.join(composeDir, "docker-compose.yml");
179
+ const auth = resolveAuthEnv(opts);
180
+ fs.writeFileSync(composePath, generateComposeFile(port, auth, infra, opts?.streamEnv ?? {}, opts?.deferAgentStart, opts?.ghToken), "utf-8");
181
+ console.log(`[docker] Compose file written: ${composePath}`);
182
+ if (infra.mode === "local") {
183
+ console.log(`[docker] Starting postgres + electric...`);
184
+ execSync(`docker compose -p ${project} -f ${composePath} up -d postgres electric`, {
185
+ stdio: "pipe",
186
+ timeout: 120_000,
187
+ });
188
+ await waitForElectric(project, composePath);
189
+ console.log(`[docker] Electric is ready`);
190
+ }
191
+ // Start the agent service in detached mode — it communicates via the durable stream
192
+ console.log(`[docker] Starting agent container...`);
193
+ execSync(`docker compose -p ${project} -f ${composePath} up -d agent`, {
194
+ stdio: "pipe",
195
+ timeout: 60_000,
196
+ });
197
+ console.log(`[docker] Agent container started`);
198
+ const handle = {
199
+ sessionId,
200
+ runtime: "docker",
201
+ port,
202
+ projectDir: `/home/agent/workspace/${opts?.projectName || sessionId.slice(0, 8)}`,
203
+ };
204
+ const state = {
205
+ composeDir,
206
+ composeProject: project,
207
+ };
208
+ this.activeContainers.set(sessionId, handle);
209
+ this.internalState.set(sessionId, state);
210
+ return handle;
211
+ }
212
+ async destroy(handle) {
213
+ const state = this.internalState.get(handle.sessionId);
214
+ this.activeContainers.delete(handle.sessionId);
215
+ this.internalState.delete(handle.sessionId);
216
+ if (!state)
217
+ return;
218
+ const composePath = path.join(state.composeDir, "docker-compose.yml");
219
+ try {
220
+ execSync(`docker compose -p ${state.composeProject} -f ${composePath} down -v --remove-orphans`, { stdio: "ignore", timeout: 30_000 });
221
+ }
222
+ catch {
223
+ // Best effort
224
+ }
225
+ setTimeout(() => {
226
+ fs.rm(state.composeDir, { recursive: true, force: true }, () => { });
227
+ }, 5000);
228
+ }
229
+ async restartAgent(handle) {
230
+ const state = this.internalState.get(handle.sessionId);
231
+ if (!state) {
232
+ throw new Error("No active container for session");
233
+ }
234
+ const composePath = path.join(state.composeDir, "docker-compose.yml");
235
+ // Stop and restart the agent service
236
+ try {
237
+ execSync(`docker compose -p ${state.composeProject} -f ${composePath} stop agent`, {
238
+ stdio: "ignore",
239
+ timeout: 15_000,
240
+ });
241
+ }
242
+ catch {
243
+ // May already be stopped
244
+ }
245
+ execSync(`docker compose -p ${state.composeProject} -f ${composePath} up -d agent`, {
246
+ stdio: "pipe",
247
+ timeout: 60_000,
248
+ });
249
+ const newHandle = {
250
+ sessionId: handle.sessionId,
251
+ runtime: "docker",
252
+ port: handle.port,
253
+ projectDir: handle.projectDir,
254
+ };
255
+ this.activeContainers.set(handle.sessionId, newHandle);
256
+ return newHandle;
257
+ }
258
+ /** Get the Docker container ID for a session's agent service */
259
+ getContainerId(sessionId) {
260
+ const state = this.internalState.get(sessionId);
261
+ if (!state)
262
+ return null;
263
+ return getAgentContainerId(state);
264
+ }
265
+ get(sessionId) {
266
+ return this.activeContainers.get(sessionId);
267
+ }
268
+ list() {
269
+ return [...this.activeContainers.values()];
270
+ }
271
+ isAlive(handle) {
272
+ const state = this.internalState.get(handle.sessionId);
273
+ if (!state)
274
+ return false;
275
+ const containerId = getAgentContainerId(state);
276
+ return containerId !== null;
277
+ }
278
+ async exec(handle, command) {
279
+ const state = this.getState(handle);
280
+ return execInContainer(state, command).trim();
281
+ }
282
+ async listFiles(handle, dir) {
283
+ const state = this.internalState.get(handle.sessionId);
284
+ if (!state)
285
+ return [];
286
+ const containerId = getAgentContainerId(state);
287
+ if (!containerId)
288
+ return [];
289
+ try {
290
+ const output = execFileSync("docker", [
291
+ "exec",
292
+ containerId,
293
+ "find",
294
+ dir,
295
+ "-type",
296
+ "f",
297
+ "-not",
298
+ "-path",
299
+ "*/node_modules/*",
300
+ "-not",
301
+ "-path",
302
+ "*/.git/*",
303
+ "-not",
304
+ "-path",
305
+ "*/dist/*",
306
+ "-not",
307
+ "-path",
308
+ "*/.next/*",
309
+ "-not",
310
+ "-path",
311
+ "*/.cache/*",
312
+ "-not",
313
+ "-path",
314
+ "*/.electric/*",
315
+ "-not",
316
+ "-name",
317
+ "pnpm-lock.yaml",
318
+ "-not",
319
+ "-name",
320
+ "package-lock.json",
321
+ ], { encoding: "utf-8", timeout: 10_000, stdio: ["ignore", "pipe", "ignore"] });
322
+ return output
323
+ .split("\n")
324
+ .map((l) => l.trim())
325
+ .filter(Boolean);
326
+ }
327
+ catch {
328
+ return [];
329
+ }
330
+ }
331
+ async readFile(handle, filePath) {
332
+ const state = this.internalState.get(handle.sessionId);
333
+ if (!state)
334
+ return null;
335
+ const containerId = getAgentContainerId(state);
336
+ if (!containerId)
337
+ return null;
338
+ try {
339
+ return execFileSync("docker", ["exec", containerId, "cat", filePath], {
340
+ encoding: "utf-8",
341
+ timeout: 5_000,
342
+ stdio: ["ignore", "pipe", "ignore"],
343
+ });
344
+ }
345
+ catch {
346
+ return null;
347
+ }
348
+ }
349
+ async startApp(handle) {
350
+ const state = this.internalState.get(handle.sessionId);
351
+ if (!state)
352
+ return false;
353
+ const containerId = getAgentContainerId(state);
354
+ if (!containerId)
355
+ return false;
356
+ try {
357
+ execFileSync("docker", ["exec", containerId, "sh", "-c", "cd /home/agent/workspace/*/ && pnpm dev:start"], { timeout: 10_000, stdio: "ignore" });
358
+ return true;
359
+ }
360
+ catch {
361
+ return false;
362
+ }
363
+ }
364
+ async stopApp(handle) {
365
+ const state = this.internalState.get(handle.sessionId);
366
+ if (!state)
367
+ return false;
368
+ const containerId = getAgentContainerId(state);
369
+ if (!containerId)
370
+ return false;
371
+ try {
372
+ execFileSync("docker", ["exec", containerId, "sh", "-c", "cd /home/agent/workspace/*/ && pnpm dev:stop"], { timeout: 5000, stdio: "ignore" });
373
+ return true;
374
+ }
375
+ catch {
376
+ return false;
377
+ }
378
+ }
379
+ async isAppRunning(handle) {
380
+ const state = this.internalState.get(handle.sessionId);
381
+ if (!state)
382
+ return false;
383
+ const containerId = getAgentContainerId(state);
384
+ if (!containerId)
385
+ return false;
386
+ try {
387
+ execFileSync("docker", [
388
+ "exec",
389
+ containerId,
390
+ "sh",
391
+ "-c",
392
+ "kill -0 $(cat /tmp/dev-server.pid 2>/dev/null) 2>/dev/null",
393
+ ], { timeout: 5000, stdio: "ignore" });
394
+ return true;
395
+ }
396
+ catch {
397
+ return false;
398
+ }
399
+ }
400
+ async gitStatus(handle, projectDir) {
401
+ const state = this.internalState.get(handle.sessionId);
402
+ if (!state) {
403
+ return {
404
+ initialized: false,
405
+ branch: null,
406
+ hasUncommitted: false,
407
+ lastCommitHash: null,
408
+ lastCommitMessage: null,
409
+ };
410
+ }
411
+ try {
412
+ const output = execInContainer(state, `cd ${projectDir} && test -d .git && echo "GIT_INIT=yes" || echo "GIT_INIT=no"`);
413
+ if (!output.includes("GIT_INIT=yes")) {
414
+ return {
415
+ initialized: false,
416
+ branch: null,
417
+ hasUncommitted: false,
418
+ lastCommitHash: null,
419
+ lastCommitMessage: null,
420
+ };
421
+ }
422
+ const branch = execInContainer(state, `cd ${projectDir} && git rev-parse --abbrev-ref HEAD 2>/dev/null || echo ""`).trim();
423
+ const hash = execInContainer(state, `cd ${projectDir} && git rev-parse HEAD 2>/dev/null || echo ""`).trim();
424
+ const message = execInContainer(state, `cd ${projectDir} && git log -1 --format=%s 2>/dev/null || echo ""`).trim();
425
+ const statusOutput = execInContainer(state, `cd ${projectDir} && git status --porcelain 2>/dev/null || echo ""`).trim();
426
+ return {
427
+ initialized: true,
428
+ branch: branch || null,
429
+ hasUncommitted: statusOutput.length > 0,
430
+ lastCommitHash: hash || null,
431
+ lastCommitMessage: message || null,
432
+ };
433
+ }
434
+ catch {
435
+ return {
436
+ initialized: false,
437
+ branch: null,
438
+ hasUncommitted: false,
439
+ lastCommitHash: null,
440
+ lastCommitMessage: null,
441
+ };
442
+ }
443
+ }
444
+ async createFromRepo(sessionId, repoUrl, opts) {
445
+ const repoName = repoUrl
446
+ .split("/")
447
+ .pop()
448
+ ?.replace(/\.git$/, "") || "resumed-project";
449
+ const handle = await this.create(sessionId, {
450
+ apiKey: opts?.apiKey,
451
+ oauthToken: opts?.oauthToken,
452
+ ghToken: opts?.ghToken,
453
+ projectName: repoName,
454
+ });
455
+ const state = this.getState(handle);
456
+ const targetDir = `/home/agent/workspace/${repoName}`;
457
+ execInContainer(state, `gh repo clone "${repoUrl}" "${targetDir}" 2>/dev/null || git clone "${repoUrl}" "${targetDir}"`, { timeout: 60_000 });
458
+ if (opts?.branch) {
459
+ execInContainer(state, `cd ${targetDir} && git checkout ${opts.branch}`);
460
+ }
461
+ handle.projectDir = targetDir;
462
+ return handle;
463
+ }
464
+ }
465
+ //# sourceMappingURL=docker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/sandbox/docker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,GAAG,MAAM,UAAU,CAAA;AAC1B,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAkB5B,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,aAAa,GAAG,wBAAwB,CAAA;AAE9C,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,SAAS,YAAY;IACpB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,CAAA;QACjC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;YAClC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;YAC7B,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;gBACtB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;YAClC,CAAC;iBAAM,CAAC;gBACP,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAA;YACvE,CAAC;QACF,CAAC,CAAC,CAAA;QACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAA+C;IACtE,IAAI,IAAI,EAAE,MAAM;QAAE,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC3D,IAAI,IAAI,EAAE,UAAU;QAAE,OAAO,CAAC,yBAAyB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;IACzE,OAAO,IAAI,CAAA;AACZ,CAAC;AAED,SAAS,mBAAmB,CAC3B,IAAY,EACZ,IAA6B,EAC7B,QAAqB,EAAE,IAAI,EAAE,OAAO,EAAE,EACtC,YAAoC,EAAE,EACtC,eAAe,GAAG,KAAK,EACvB,OAAgB;IAEhB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,OAAO,CAAA;IAEtC,MAAM,QAAQ,GAAG;QAChB,gBAAgB,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,uDAAuD,EAAE;QACvG,gBAAgB,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,sBAAsB,EAAE;QACtE,gBAAgB;QAChB,gBAAgB;KAChB,CAAA;IACD,IAAI,OAAO,EAAE,CAAC;QACb,QAAQ,CAAC,IAAI,CAAC,sBAAsB,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;QACrD,QAAQ,CAAC,IAAI,CAAC,mBAAmB,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;IACjD,CAAC;IACD,IAAI,IAAI,EAAE,CAAC;QACV,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IACvC,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACb,QAAQ,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,CAAC,CAAA;IACrC,CAAC;IAED,+DAA+D;IAC/D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACtD,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAA;IACjC,CAAC;IAED,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEnE,qFAAqF;IACrF,wDAAwD;IACxD,MAAM,YAAY,GAAG,eAAe;QACnC,CAAC,CAAC,6BAA6B;QAC/B,CAAC,CAAC,gCAAgC,CAAA;IAEnC,IAAI,OAAO,EAAE,CAAC;QACb,OAAO;;aAEI,aAAa;;WAEf,IAAI;;EAEb,YAAY;;;;eAIC,YAAY;;;;CAI1B,CAAA;IACA,CAAC;IAED,OAAO;;;;;;;;;;;;;;;;;;;;;;;;aAwBK,aAAa;;WAEf,IAAI;;EAEb,YAAY;;;;;;;eAOC,YAAY;;;;CAI1B,CAAA;AACD,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,OAAe,EAAE,WAAmB;IAClE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC;QACpC,IAAI,CAAC;YACJ,QAAQ,CACP,qBAAqB,OAAO,OAAO,WAAW,4DAA4D,EAC1G,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAClC,CAAA;YACD,OAAM;QACP,CAAC;QAAC,MAAM,CAAC;YACR,gBAAgB;QACjB,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;IAC9C,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;AAC3D,CAAC;AAED,SAAS,mBAAmB,CAAC,KAA0B;IACtD,IAAI,CAAC;QACJ,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAA;QACrE,MAAM,EAAE,GAAG,YAAY,CACtB,QAAQ,EACR,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAC/E,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CACzE,CAAC,IAAI,EAAE,CAAA;QACR,OAAO,EAAE,IAAI,IAAI,CAAA;IAClB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAA;IACZ,CAAC;AACF,CAAC;AAED,SAAS,eAAe,CACvB,KAA0B,EAC1B,OAAe,EACf,IAA2B;IAE3B,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;IAC9C,IAAI,CAAC,WAAW;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAA;IACzD,OAAO,YAAY,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE;QACzE,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,MAAM;QAChC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KACjC,CAAC,CAAA;AACH,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,MAAM,OAAO,qBAAqB;IACxB,OAAO,GAAG,QAAiB,CAAA;IAE5B,gBAAgB,GAAG,IAAI,GAAG,EAAyB,CAAA;IACnD,aAAa,GAAG,IAAI,GAAG,EAA+B,CAAA;IAEtD,QAAQ,CAAC,MAAqB;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;QAChF,OAAO,KAAK,CAAA;IACb,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAiB,EAAE,IAAwB;QACvD,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;QACjC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,WAAW,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;aACvD,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;aAC5B,WAAW,EAAE,CAAA;QACf,MAAM,OAAO,GAAG,MAAM,IAAI,EAAE,CAAA;QAC5B,MAAM,KAAK,GAAgB,IAAI,EAAE,KAAK,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;QAE3D,OAAO,CAAC,GAAG,CACV,sCAAsC,SAAS,YAAY,OAAO,SAAS,IAAI,UAAU,KAAK,CAAC,IAAI,EAAE,CACrG,CAAA;QAED,MAAM,UAAU,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,CAAA;QACxE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAA;QAC/D,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;QACjC,EAAE,CAAC,aAAa,CACf,WAAW,EACX,mBAAmB,CAClB,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,IAAI,EAAE,SAAS,IAAI,EAAE,EACrB,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,OAAO,CACb,EACD,OAAO,CACP,CAAA;QACD,OAAO,CAAC,GAAG,CAAC,kCAAkC,WAAW,EAAE,CAAC,CAAA;QAE5D,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAA;YACvD,QAAQ,CAAC,qBAAqB,OAAO,OAAO,WAAW,0BAA0B,EAAE;gBAClF,KAAK,EAAE,MAAM;gBACb,OAAO,EAAE,OAAO;aAChB,CAAC,CAAA;YACF,MAAM,eAAe,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;YAC3C,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAA;QAC1C,CAAC;QAED,oFAAoF;QACpF,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAA;QACnD,QAAQ,CAAC,qBAAqB,OAAO,OAAO,WAAW,cAAc,EAAE;YACtE,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,MAAM;SACf,CAAC,CAAA;QACF,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAA;QAE/C,MAAM,MAAM,GAAkB;YAC7B,SAAS;YACT,OAAO,EAAE,QAAQ;YACjB,IAAI;YACJ,UAAU,EAAE,yBAAyB,IAAI,EAAE,WAAW,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;SACjF,CAAA;QAED,MAAM,KAAK,GAAwB;YAClC,UAAU;YACV,cAAc,EAAE,OAAO;SACvB,CAAA;QAED,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QAC5C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QAExC,OAAO,MAAM,CAAA;IACd,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAqB;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC9C,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAE3C,IAAI,CAAC,KAAK;YAAE,OAAM;QAElB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAA;QACrE,IAAI,CAAC;YACJ,QAAQ,CACP,qBAAqB,KAAK,CAAC,cAAc,OAAO,WAAW,2BAA2B,EACtF,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CACpC,CAAA;QACF,CAAC;QAAC,MAAM,CAAC;YACR,cAAc;QACf,CAAC;QACD,UAAU,CAAC,GAAG,EAAE;YACf,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QACpE,CAAC,EAAE,IAAI,CAAC,CAAA;IACT,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAqB;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;QACnD,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAA;QAErE,qCAAqC;QACrC,IAAI,CAAC;YACJ,QAAQ,CAAC,qBAAqB,KAAK,CAAC,cAAc,OAAO,WAAW,aAAa,EAAE;gBAClF,KAAK,EAAE,QAAQ;gBACf,OAAO,EAAE,MAAM;aACf,CAAC,CAAA;QACH,CAAC;QAAC,MAAM,CAAC;YACR,yBAAyB;QAC1B,CAAC;QAED,QAAQ,CAAC,qBAAqB,KAAK,CAAC,cAAc,OAAO,WAAW,cAAc,EAAE;YACnF,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,MAAM;SACf,CAAC,CAAA;QAEF,MAAM,SAAS,GAAkB;YAChC,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,QAAQ;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,UAAU,EAAE,MAAM,CAAC,UAAU;SAC7B,CAAA;QAED,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QAEtD,OAAO,SAAS,CAAA;IACjB,CAAC;IAED,gEAAgE;IAChE,cAAc,CAAC,SAAiB;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAC/C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QACvB,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAA;IAClC,CAAC;IAED,GAAG,CAAC,SAAiB;QACpB,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC5C,CAAC;IAED,IAAI;QACH,OAAO,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAA;IAC3C,CAAC;IAED,OAAO,CAAC,MAAqB;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAA;QACxB,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;QAC9C,OAAO,WAAW,KAAK,IAAI,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAqB,EAAE,OAAe;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QACnC,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAA;IAC9C,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,MAAqB,EAAE,GAAW;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAA;QAErB,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;QAC9C,IAAI,CAAC,WAAW;YAAE,OAAO,EAAE,CAAA;QAE3B,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,YAAY,CAC1B,QAAQ,EACR;gBACC,MAAM;gBACN,WAAW;gBACX,MAAM;gBACN,GAAG;gBACH,OAAO;gBACP,GAAG;gBACH,MAAM;gBACN,OAAO;gBACP,kBAAkB;gBAClB,MAAM;gBACN,OAAO;gBACP,UAAU;gBACV,MAAM;gBACN,OAAO;gBACP,UAAU;gBACV,MAAM;gBACN,OAAO;gBACP,WAAW;gBACX,MAAM;gBACN,OAAO;gBACP,YAAY;gBACZ,MAAM;gBACN,OAAO;gBACP,eAAe;gBACf,MAAM;gBACN,OAAO;gBACP,gBAAgB;gBAChB,MAAM;gBACN,OAAO;gBACP,mBAAmB;aACnB,EACD,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAC3E,CAAA;YACD,OAAO,MAAM;iBACX,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,MAAM,CAAC,OAAO,CAAC,CAAA;QAClB,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,EAAE,CAAA;QACV,CAAC;IACF,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAqB,EAAE,QAAgB;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAEvB,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;QAC9C,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAA;QAE7B,IAAI,CAAC;YACJ,OAAO,YAAY,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE;gBACrE,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;aACnC,CAAC,CAAA;QACH,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,IAAI,CAAA;QACZ,CAAC;IACF,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAqB;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAA;QAExB,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;QAC9C,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAA;QAE9B,IAAI,CAAC;YACJ,YAAY,CACX,QAAQ,EACR,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,+CAA+C,CAAC,EAClF,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CACpC,CAAA;YACD,OAAO,IAAI,CAAA;QACZ,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAA;QACb,CAAC;IACF,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAqB;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAA;QAExB,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;QAC9C,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAA;QAE9B,IAAI,CAAC;YACJ,YAAY,CACX,QAAQ,EACR,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,8CAA8C,CAAC,EACjF,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAClC,CAAA;YACD,OAAO,IAAI,CAAA;QACZ,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAA;QACb,CAAC;IACF,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAqB;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAA;QAExB,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;QAC9C,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAA;QAE9B,IAAI,CAAC;YACJ,YAAY,CACX,QAAQ,EACR;gBACC,MAAM;gBACN,WAAW;gBACX,IAAI;gBACJ,IAAI;gBACJ,4DAA4D;aAC5D,EACD,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAClC,CAAA;YACD,OAAO,IAAI,CAAA;QACZ,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAA;QACb,CAAC;IACF,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,MAAqB,EAAE,UAAkB;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,OAAO;gBACN,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,IAAI;gBACZ,cAAc,EAAE,KAAK;gBACrB,cAAc,EAAE,IAAI;gBACpB,iBAAiB,EAAE,IAAI;aACvB,CAAA;QACF,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,eAAe,CAC7B,KAAK,EACL,MAAM,UAAU,+DAA+D,CAC/E,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;gBACtC,OAAO;oBACN,WAAW,EAAE,KAAK;oBAClB,MAAM,EAAE,IAAI;oBACZ,cAAc,EAAE,KAAK;oBACrB,cAAc,EAAE,IAAI;oBACpB,iBAAiB,EAAE,IAAI;iBACvB,CAAA;YACF,CAAC;YAED,MAAM,MAAM,GAAG,eAAe,CAC7B,KAAK,EACL,MAAM,UAAU,4DAA4D,CAC5E,CAAC,IAAI,EAAE,CAAA;YACR,MAAM,IAAI,GAAG,eAAe,CAC3B,KAAK,EACL,MAAM,UAAU,+CAA+C,CAC/D,CAAC,IAAI,EAAE,CAAA;YACR,MAAM,OAAO,GAAG,eAAe,CAC9B,KAAK,EACL,MAAM,UAAU,mDAAmD,CACnE,CAAC,IAAI,EAAE,CAAA;YACR,MAAM,YAAY,GAAG,eAAe,CACnC,KAAK,EACL,MAAM,UAAU,mDAAmD,CACnE,CAAC,IAAI,EAAE,CAAA;YAER,OAAO;gBACN,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,MAAM,IAAI,IAAI;gBACtB,cAAc,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC;gBACvC,cAAc,EAAE,IAAI,IAAI,IAAI;gBAC5B,iBAAiB,EAAE,OAAO,IAAI,IAAI;aAClC,CAAA;QACF,CAAC;QAAC,MAAM,CAAC;YACR,OAAO;gBACN,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,IAAI;gBACZ,cAAc,EAAE,KAAK;gBACrB,cAAc,EAAE,IAAI;gBACpB,iBAAiB,EAAE,IAAI;aACvB,CAAA;QACF,CAAC;IACF,CAAC;IAED,KAAK,CAAC,cAAc,CACnB,SAAiB,EACjB,OAAe,EACf,IAAkF;QAElF,MAAM,QAAQ,GACb,OAAO;aACL,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,EAAE;YACN,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,iBAAiB,CAAA;QAE9C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;YAC3C,MAAM,EAAE,IAAI,EAAE,MAAM;YACpB,UAAU,EAAE,IAAI,EAAE,UAAU;YAC5B,OAAO,EAAE,IAAI,EAAE,OAAO;YACtB,WAAW,EAAE,QAAQ;SACrB,CAAC,CAAA;QACF,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QAEnC,MAAM,SAAS,GAAG,yBAAyB,QAAQ,EAAE,CAAA;QACrD,eAAe,CACd,KAAK,EACL,kBAAkB,OAAO,MAAM,SAAS,+BAA+B,OAAO,MAAM,SAAS,GAAG,EAChG,EAAE,OAAO,EAAE,MAAM,EAAE,CACnB,CAAA;QAED,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;YAClB,eAAe,CAAC,KAAK,EAAE,MAAM,SAAS,oBAAoB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;QACzE,CAAC;QAED,MAAM,CAAC,UAAU,GAAG,SAAS,CAAA;QAC7B,OAAO,MAAM,CAAA;IACd,CAAC;CACD"}
@@ -0,0 +1,5 @@
1
+ export { DaytonaSandboxProvider } from "./daytona.js";
2
+ export { DockerSandboxProvider } from "./docker.js";
3
+ export { SpritesSandboxProvider } from "./sprites.js";
4
+ export type { CreateSandboxOpts, GitStatus, InfraConfig, SandboxHandle, SandboxProvider, SandboxRuntime, } from "./types.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AACrD,YAAY,EACX,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,aAAa,EACb,eAAe,EACf,cAAc,GACd,MAAM,YAAY,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { DaytonaSandboxProvider } from "./daytona.js";
2
+ export { DockerSandboxProvider } from "./docker.js";
3
+ export { SpritesSandboxProvider } from "./sprites.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Bootstrap logic for Sprites sandboxes.
3
+ *
4
+ * Sprites run Ubuntu 24.04 with Node.js pre-installed but no project tooling.
5
+ * This module installs the required tools (pnpm, electric-agent) and creates
6
+ * a checkpoint so subsequent sprites can restore instantly.
7
+ */
8
+ import type { Sprite } from "@fly/sprites";
9
+ export interface BootstrapOptions {
10
+ /** Custom package URL (e.g. pkg-pr-new preview) to install instead of the published electric-agent */
11
+ packageUrl?: string;
12
+ }
13
+ /**
14
+ * Bootstrap a sprite by installing required global tools.
15
+ * This runs inside a freshly-created sprite that has Node.js but nothing else.
16
+ */
17
+ export declare function bootstrapSprite(sprite: Sprite, opts?: BootstrapOptions): Promise<void>;
18
+ /**
19
+ * Ensure the sprite is bootstrapped. If a matching checkpoint exists,
20
+ * restore from it. Otherwise, run the full bootstrap and create a checkpoint.
21
+ *
22
+ * When a custom packageUrl is provided (e.g. PR preview), the checkpoint
23
+ * comment includes a hash of the URL so different versions don't collide.
24
+ */
25
+ export declare function ensureBootstrapped(sprite: Sprite, opts?: BootstrapOptions): Promise<void>;
26
+ //# sourceMappingURL=sprites-bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sprites-bootstrap.d.ts","sourceRoot":"","sources":["../../src/sandbox/sprites-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAO1C,MAAM,WAAW,gBAAgB;IAChC,sGAAsG;IACtG,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoD5F;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC/F"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Bootstrap logic for Sprites sandboxes.
3
+ *
4
+ * Sprites run Ubuntu 24.04 with Node.js pre-installed but no project tooling.
5
+ * This module installs the required tools (pnpm, electric-agent) and creates
6
+ * a checkpoint so subsequent sprites can restore instantly.
7
+ */
8
+ import { createRequire } from "node:module";
9
+ const require = createRequire(import.meta.url);
10
+ const { version } = require("../../package.json");
11
+ const CHECKPOINT_COMMENT = `bootstrapped:${version}`;
12
+ /**
13
+ * Bootstrap a sprite by installing required global tools.
14
+ * This runs inside a freshly-created sprite that has Node.js but nothing else.
15
+ */
16
+ export async function bootstrapSprite(sprite, opts) {
17
+ const packageSpec = opts?.packageUrl ?? "electric-agent";
18
+ console.log(`[sprites-bootstrap] Installing pnpm...`);
19
+ await sprite.exec("npm install -g pnpm", { maxBuffer: 50 * 1024 * 1024 });
20
+ console.log(`[sprites-bootstrap] Installing electric-agent from: ${packageSpec}`);
21
+ await sprite.execFile("bash", [
22
+ "-c",
23
+ `source /etc/profile.d/npm-global.sh 2>/dev/null; npm install -g ${packageSpec}`,
24
+ ]);
25
+ // Create the workspace directory structure matching other runtimes
26
+ await sprite.exec("mkdir -p /home/agent/workspace");
27
+ // Write a profile script that adds npm global bin and nvm paths to PATH.
28
+ // Sprites use nvm-managed Node.js — the bin dir isn't in the default PATH
29
+ // when running commands via sprite.execFile("bash", ["-c", ...]).
30
+ await sprite.execFile("bash", [
31
+ "-c",
32
+ [
33
+ // Source nvm if present (sets up node/npm/npx in PATH)
34
+ 'export NVM_DIR="/.sprite/languages/node/nvm"',
35
+ '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"',
36
+ // Get the npm global bin path and write it to a profile script
37
+ 'NPM_BIN="$(npm config get prefix)/bin"',
38
+ 'echo "export PATH=\\"$NPM_BIN:\\$PATH\\"" > /etc/profile.d/npm-global.sh',
39
+ // Also add nvm init to the profile so node/npm are always available
40
+ 'echo "export NVM_DIR=\\"/.sprite/languages/node/nvm\\"" >> /etc/profile.d/npm-global.sh',
41
+ 'echo "[ -s \\"\\$NVM_DIR/nvm.sh\\" ] && . \\"\\$NVM_DIR/nvm.sh\\"" >> /etc/profile.d/npm-global.sh',
42
+ ].join(" && "),
43
+ ]);
44
+ // Configure git (needed for the git agent)
45
+ // Use execFile to avoid sprite.exec() splitting quoted args by whitespace
46
+ await sprite.execFile("git", ["config", "--global", "user.name", "electric-agent"]);
47
+ await sprite.execFile("git", ["config", "--global", "user.email", "agent@electric-sql.com"]);
48
+ await sprite.execFile("git", ["config", "--global", "init.defaultBranch", "main"]);
49
+ // Configure gh as the git credential helper so `git push` authenticates
50
+ // via GH_TOKEN. Without this, HTTPS pushes fail in the sandbox because
51
+ // there's no interactive terminal for git to prompt for credentials.
52
+ // Note: gh auth setup-git only writes the credential.helper config —
53
+ // it doesn't need GH_TOKEN at this point. The token is read at push time.
54
+ await sprite.execFile("git", [
55
+ "config",
56
+ "--global",
57
+ "credential.helper",
58
+ "!gh auth git-credential",
59
+ ]);
60
+ console.log(`[sprites-bootstrap] Bootstrap complete (electric-agent@${version})`);
61
+ }
62
+ /**
63
+ * Ensure the sprite is bootstrapped. If a matching checkpoint exists,
64
+ * restore from it. Otherwise, run the full bootstrap and create a checkpoint.
65
+ *
66
+ * When a custom packageUrl is provided (e.g. PR preview), the checkpoint
67
+ * comment includes a hash of the URL so different versions don't collide.
68
+ */
69
+ export async function ensureBootstrapped(sprite, opts) {
70
+ const comment = opts?.packageUrl
71
+ ? `${CHECKPOINT_COMMENT}:${shortHash(opts.packageUrl)}`
72
+ : CHECKPOINT_COMMENT;
73
+ // Check for existing checkpoint
74
+ try {
75
+ const checkpoints = await sprite.listCheckpoints();
76
+ const bootstrapped = checkpoints.find((cp) => cp.comment === comment);
77
+ if (bootstrapped) {
78
+ console.log(`[sprites-bootstrap] Restoring from checkpoint "${bootstrapped.id}" (electric-agent@${version})`);
79
+ const response = await sprite.restoreCheckpoint(bootstrapped.id);
80
+ // Consume the NDJSON response stream to completion
81
+ await consumeStream(response);
82
+ console.log(`[sprites-bootstrap] Restored from checkpoint`);
83
+ return;
84
+ }
85
+ }
86
+ catch {
87
+ // No checkpoints yet — proceed with bootstrap
88
+ }
89
+ // Run full bootstrap
90
+ await bootstrapSprite(sprite, opts);
91
+ // Create checkpoint for future reuse
92
+ console.log(`[sprites-bootstrap] Creating checkpoint...`);
93
+ try {
94
+ const response = await sprite.createCheckpoint(comment);
95
+ await consumeStream(response);
96
+ console.log(`[sprites-bootstrap] Checkpoint created`);
97
+ }
98
+ catch (err) {
99
+ // Non-fatal — next creation will just bootstrap again
100
+ console.warn(`[sprites-bootstrap] Failed to create checkpoint:`, err);
101
+ }
102
+ }
103
+ /** Consume a streaming Response body to completion */
104
+ async function consumeStream(response) {
105
+ if (!response.body)
106
+ return;
107
+ const reader = response.body.getReader();
108
+ try {
109
+ while (true) {
110
+ const { done } = await reader.read();
111
+ if (done)
112
+ break;
113
+ }
114
+ }
115
+ finally {
116
+ reader.releaseLock();
117
+ }
118
+ }
119
+ /** Simple string hash for checkpoint disambiguation */
120
+ function shortHash(input) {
121
+ let hash = 0;
122
+ for (let i = 0; i < input.length; i++) {
123
+ hash = ((hash << 5) - hash + input.charCodeAt(i)) | 0;
124
+ }
125
+ return (hash >>> 0).toString(36);
126
+ }
127
+ //# sourceMappingURL=sprites-bootstrap.js.map