noumen 0.3.0 → 0.5.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 (44) hide show
  1. package/README.md +63 -8
  2. package/dist/a2a/index.d.ts +4 -2
  3. package/dist/acp/index.d.ts +5 -3
  4. package/dist/{agent-1nFVUP9E.d.ts → agent-C3eDRsxs.d.ts} +19 -508
  5. package/dist/chunk-I5SBSOS6.js +40 -0
  6. package/dist/chunk-I5SBSOS6.js.map +1 -0
  7. package/dist/{chunk-4HW6LN6D.js → chunk-WPCYGZOE.js} +58 -1228
  8. package/dist/chunk-WPCYGZOE.js.map +1 -0
  9. package/dist/{chunk-5JN4SPI7.js → chunk-WTLK2ZAR.js} +1 -1
  10. package/dist/{chunk-HL6JCRZJ.js → chunk-XZN4QZLK.js} +4 -4
  11. package/dist/cli/index.js +10 -10
  12. package/dist/computer-BPdxSo6X.d.ts +88 -0
  13. package/dist/docker.d.ts +129 -0
  14. package/dist/docker.js +401 -0
  15. package/dist/docker.js.map +1 -0
  16. package/dist/e2b.d.ts +157 -0
  17. package/dist/e2b.js +202 -0
  18. package/dist/e2b.js.map +1 -0
  19. package/dist/freestyle.d.ts +174 -0
  20. package/dist/freestyle.js +240 -0
  21. package/dist/freestyle.js.map +1 -0
  22. package/dist/index.d.ts +9 -201
  23. package/dist/index.js +24 -48
  24. package/dist/lsp/index.d.ts +3 -2
  25. package/dist/mcp/index.d.ts +4 -3
  26. package/dist/mcp/index.js +2 -2
  27. package/dist/{provider-factory-KCLIF34X.js → provider-factory-KI7OZUY3.js} +2 -2
  28. package/dist/{resolve-4JA2BBDA.js → resolve-GDSHNMG6.js} +2 -2
  29. package/dist/sandbox-9qeMTNrD.d.ts +126 -0
  30. package/dist/server/index.d.ts +4 -2
  31. package/dist/{server-CHMxuWKq.d.ts → server-Cu9gv1dk.d.ts} +1 -1
  32. package/dist/sprites.d.ts +136 -0
  33. package/dist/sprites.js +334 -0
  34. package/dist/sprites.js.map +1 -0
  35. package/dist/ssh.d.ts +187 -0
  36. package/dist/ssh.js +392 -0
  37. package/dist/ssh.js.map +1 -0
  38. package/dist/{types-RPKUTu1k.d.ts → types-BA87bHPV.d.ts} +2 -88
  39. package/package.json +28 -1
  40. package/dist/chunk-4HW6LN6D.js.map +0 -1
  41. /package/dist/{chunk-5JN4SPI7.js.map → chunk-WTLK2ZAR.js.map} +0 -0
  42. /package/dist/{chunk-HL6JCRZJ.js.map → chunk-XZN4QZLK.js.map} +0 -0
  43. /package/dist/{provider-factory-KCLIF34X.js.map → provider-factory-KI7OZUY3.js.map} +0 -0
  44. /package/dist/{resolve-4JA2BBDA.js.map → resolve-GDSHNMG6.js.map} +0 -0
@@ -1,6 +1,13 @@
1
1
  import {
2
2
  applySnipRemovals
3
3
  } from "./chunk-42PHHZUA.js";
4
+ import {
5
+ ToolRegistry,
6
+ createToolSearchTool,
7
+ isPathInWorkingDirectories,
8
+ resolvePermission,
9
+ resolveToolFlag
10
+ } from "./chunk-XZN4QZLK.js";
4
11
  import {
5
12
  getAutoCompactThreshold,
6
13
  getEffectiveContextWindow,
@@ -12,13 +19,6 @@ import {
12
19
  import {
13
20
  generateUUID
14
21
  } from "./chunk-3HEYCV26.js";
15
- import {
16
- ToolRegistry,
17
- createToolSearchTool,
18
- isPathInWorkingDirectories,
19
- resolvePermission,
20
- resolveToolFlag
21
- } from "./chunk-HL6JCRZJ.js";
22
22
  import {
23
23
  contentToString,
24
24
  hasImageContent,
@@ -178,7 +178,7 @@ var LocalComputer = class {
178
178
  this.defaultTimeout = opts?.defaultTimeout ?? 3e4;
179
179
  }
180
180
  executeCommand(command, opts) {
181
- return new Promise((resolve7) => {
181
+ return new Promise((resolve3) => {
182
182
  const child = execCb(
183
183
  command,
184
184
  {
@@ -189,7 +189,7 @@ var LocalComputer = class {
189
189
  shell: process.env.SHELL || "/bin/sh"
190
190
  },
191
191
  (error, stdout, stderr) => {
192
- resolve7({
192
+ resolve3({
193
193
  exitCode: error && "code" in error ? typeof error.code === "number" ? error.code : 1 : child.exitCode ?? 0,
194
194
  stdout: stdout ?? "",
195
195
  stderr: stderr ?? ""
@@ -250,7 +250,7 @@ var SandboxedLocalComputer = class {
250
250
  async executeCommand(command, opts) {
251
251
  await this.ensureInitialized();
252
252
  const wrappedCommand = await SandboxManager.wrapWithSandbox(command);
253
- return new Promise((resolve7) => {
253
+ return new Promise((resolve3) => {
254
254
  const child = execCb2(
255
255
  wrappedCommand,
256
256
  {
@@ -266,7 +266,7 @@ var SandboxedLocalComputer = class {
266
266
  stdout: stdout ?? "",
267
267
  stderr: stderr ?? ""
268
268
  };
269
- Promise.resolve(SandboxManager.cleanupAfterCommand()).then(() => resolve7(result)).catch(() => resolve7(result));
269
+ Promise.resolve(SandboxManager.cleanupAfterCommand()).then(() => resolve3(result)).catch(() => resolve3(result));
270
270
  }
271
271
  );
272
272
  });
@@ -283,813 +283,7 @@ var SandboxedLocalComputer = class {
283
283
  }
284
284
  };
285
285
 
286
- // src/virtual/sprites-fs.ts
287
- import * as path2 from "path";
288
- var SpritesFs = class {
289
- token;
290
- spriteName;
291
- baseURL;
292
- workingDir;
293
- constructor(opts) {
294
- this.token = opts.token;
295
- this.spriteName = opts.spriteName;
296
- this.baseURL = (opts.baseURL ?? "https://api.sprites.dev").replace(
297
- /\/$/,
298
- ""
299
- );
300
- this.workingDir = opts.workingDir ?? "/home/sprite";
301
- }
302
- fsUrl(endpoint, params) {
303
- const url = new URL(
304
- `${this.baseURL}/v1/sprites/${this.spriteName}/fs${endpoint}`
305
- );
306
- if (params) {
307
- for (const [k, v] of Object.entries(params)) {
308
- url.searchParams.set(k, v);
309
- }
310
- }
311
- return url.toString();
312
- }
313
- resolvePath(p) {
314
- const normalizedBase = this.workingDir.endsWith("/") ? this.workingDir : this.workingDir + "/";
315
- if (p.startsWith("/")) {
316
- if (p !== this.workingDir && !p.startsWith(normalizedBase)) {
317
- throw new Error(`Absolute path "${p}" is outside working directory "${this.workingDir}"`);
318
- }
319
- return p;
320
- }
321
- const resolved = path2.resolve(this.workingDir, p);
322
- if (resolved !== this.workingDir && !resolved.startsWith(normalizedBase)) {
323
- throw new Error(`Path "${p}" escapes working directory "${this.workingDir}"`);
324
- }
325
- return resolved;
326
- }
327
- headers() {
328
- return {
329
- Authorization: `Bearer ${this.token}`
330
- };
331
- }
332
- async readFile(filePath, _opts) {
333
- const url = this.fsUrl("/read", { path: this.resolvePath(filePath) });
334
- const res = await fetch(url, { headers: this.headers() });
335
- if (!res.ok) {
336
- throw new Error(
337
- `SpritesFs readFile failed (${res.status}): ${await res.text()}`
338
- );
339
- }
340
- return res.text();
341
- }
342
- async readFileBytes(filePath, maxBytes) {
343
- const url = this.fsUrl("/read", {
344
- path: this.resolvePath(filePath),
345
- binary: "true"
346
- });
347
- const res = await fetch(url, { headers: this.headers() });
348
- if (!res.ok) {
349
- throw new Error(
350
- `SpritesFs readFileBytes failed (${res.status}): ${await res.text()}`
351
- );
352
- }
353
- const arrayBuf = await res.arrayBuffer();
354
- const buf = Buffer.from(arrayBuf);
355
- if (maxBytes !== void 0 && buf.length > maxBytes) {
356
- return buf.subarray(0, maxBytes);
357
- }
358
- return buf;
359
- }
360
- async writeFile(filePath, content) {
361
- const url = this.fsUrl("/write");
362
- const res = await fetch(url, {
363
- method: "POST",
364
- headers: {
365
- ...this.headers(),
366
- "Content-Type": "application/json"
367
- },
368
- body: JSON.stringify({
369
- path: this.resolvePath(filePath),
370
- content
371
- })
372
- });
373
- if (!res.ok) {
374
- throw new Error(
375
- `SpritesFs writeFile failed (${res.status}): ${await res.text()}`
376
- );
377
- }
378
- }
379
- /**
380
- * @warning Not atomic. Concurrent appends may lose data due to
381
- * read-then-write TOCTOU. The Sprites API does not expose an append primitive.
382
- */
383
- async appendFile(filePath, content) {
384
- let existing = "";
385
- try {
386
- existing = await this.readFile(filePath);
387
- } catch {
388
- }
389
- await this.writeFile(filePath, existing + content);
390
- }
391
- async deleteFile(filePath, opts) {
392
- const url = this.fsUrl("/remove");
393
- const res = await fetch(url, {
394
- method: "POST",
395
- headers: {
396
- ...this.headers(),
397
- "Content-Type": "application/json"
398
- },
399
- body: JSON.stringify({
400
- path: this.resolvePath(filePath),
401
- recursive: opts?.recursive ?? false
402
- })
403
- });
404
- if (!res.ok) {
405
- throw new Error(
406
- `SpritesFs deleteFile failed (${res.status}): ${await res.text()}`
407
- );
408
- }
409
- }
410
- async mkdir(dirPath, opts) {
411
- const url = this.fsUrl("/mkdir");
412
- const res = await fetch(url, {
413
- method: "POST",
414
- headers: {
415
- ...this.headers(),
416
- "Content-Type": "application/json"
417
- },
418
- body: JSON.stringify({
419
- path: this.resolvePath(dirPath),
420
- recursive: opts?.recursive ?? false
421
- })
422
- });
423
- if (!res.ok) {
424
- throw new Error(
425
- `SpritesFs mkdir failed (${res.status}): ${await res.text()}`
426
- );
427
- }
428
- }
429
- async readdir(dirPath, _opts) {
430
- const url = this.fsUrl("/readdir", { path: this.resolvePath(dirPath) });
431
- const res = await fetch(url, { headers: this.headers() });
432
- if (!res.ok) {
433
- throw new Error(
434
- `SpritesFs readdir failed (${res.status}): ${await res.text()}`
435
- );
436
- }
437
- const data = await res.json();
438
- return data.map((entry) => ({
439
- name: entry.name,
440
- path: entry.path,
441
- isDirectory: entry.is_dir,
442
- isFile: !entry.is_dir,
443
- size: entry.size
444
- }));
445
- }
446
- async exists(filePath) {
447
- try {
448
- await this.stat(filePath);
449
- return true;
450
- } catch {
451
- return false;
452
- }
453
- }
454
- async stat(filePath) {
455
- const url = this.fsUrl("/stat", { path: this.resolvePath(filePath) });
456
- const res = await fetch(url, { headers: this.headers() });
457
- if (!res.ok) {
458
- throw new Error(
459
- `SpritesFs stat failed (${res.status}): ${await res.text()}`
460
- );
461
- }
462
- const data = await res.json();
463
- return {
464
- size: data.size,
465
- isDirectory: data.is_dir,
466
- isFile: !data.is_dir,
467
- createdAt: data.created_at ? new Date(data.created_at) : void 0,
468
- modifiedAt: data.modified_at ? new Date(data.modified_at) : void 0
469
- };
470
- }
471
- };
472
-
473
- // src/virtual/sprites-computer.ts
474
- var SpritesComputer = class {
475
- token;
476
- spriteName;
477
- baseURL;
478
- workingDir;
479
- constructor(opts) {
480
- this.token = opts.token;
481
- this.spriteName = opts.spriteName;
482
- this.baseURL = (opts.baseURL ?? "https://api.sprites.dev").replace(
483
- /\/$/,
484
- ""
485
- );
486
- this.workingDir = opts.workingDir ?? "/home/sprite";
487
- }
488
- headers() {
489
- return {
490
- Authorization: `Bearer ${this.token}`,
491
- "Content-Type": "application/json"
492
- };
493
- }
494
- async executeCommand(command, opts) {
495
- const cwd = opts?.cwd ?? this.workingDir;
496
- const wrappedCommand = `cd ${this.shellEscape(cwd)} && ${command}`;
497
- const url = `${this.baseURL}/v1/sprites/${this.spriteName}/exec`;
498
- const res = await fetch(url, {
499
- method: "POST",
500
- headers: this.headers(),
501
- body: JSON.stringify({
502
- command: ["bash", "-c", wrappedCommand],
503
- timeout: opts?.timeout ?? 3e4,
504
- env: opts?.env
505
- })
506
- });
507
- if (!res.ok) {
508
- const text = await res.text();
509
- return {
510
- exitCode: 1,
511
- stdout: "",
512
- stderr: `Sprites exec failed (${res.status}): ${text}`
513
- };
514
- }
515
- const data = await res.json();
516
- return {
517
- exitCode: data.exit_code,
518
- stdout: data.stdout ?? "",
519
- stderr: data.stderr ?? ""
520
- };
521
- }
522
- shellEscape(s) {
523
- return `'${s.replace(/'/g, "'\\''")}'`;
524
- }
525
- };
526
-
527
- // src/virtual/docker-fs.ts
528
- import * as path3 from "path";
529
- var DockerFs = class {
530
- container;
531
- workingDir;
532
- constructor(opts) {
533
- this.container = opts.container;
534
- this.workingDir = opts.workingDir ?? "/";
535
- }
536
- resolvePath(p) {
537
- if (p.includes("\0")) {
538
- throw new Error("Path contains null bytes");
539
- }
540
- const normalizedBase = this.workingDir.endsWith("/") ? this.workingDir : this.workingDir + "/";
541
- if (p.startsWith("/")) {
542
- const normalized = path3.normalize(p);
543
- if (normalized !== this.workingDir && !normalized.startsWith(normalizedBase)) {
544
- throw new Error(`Absolute path "${p}" is outside working directory "${this.workingDir}"`);
545
- }
546
- return normalized;
547
- }
548
- const resolved = path3.resolve(this.workingDir, p);
549
- if (resolved !== this.workingDir && !resolved.startsWith(normalizedBase)) {
550
- throw new Error(`Path "${p}" escapes working directory "${this.workingDir}"`);
551
- }
552
- return resolved;
553
- }
554
- async exec(cmd) {
555
- const execInstance = await this.container.exec({
556
- Cmd: cmd,
557
- AttachStdout: true,
558
- AttachStderr: true,
559
- Tty: false
560
- });
561
- const stream = await execInstance.start({ hijack: true, stdin: false });
562
- const result = await collectExecStream(stream);
563
- const inspection = await execInstance.inspect();
564
- return { exitCode: inspection.ExitCode, ...result };
565
- }
566
- async readFile(path6, _opts) {
567
- const resolved = this.resolvePath(path6);
568
- const { exitCode, stdout, stderr } = await this.exec([
569
- "cat",
570
- resolved
571
- ]);
572
- if (exitCode !== 0) {
573
- throw new Error(`DockerFs readFile failed: ${stderr.trim() || `exit code ${exitCode}`}`);
574
- }
575
- return stdout;
576
- }
577
- async readFileBytes(path6, maxBytes) {
578
- const resolved = this.resolvePath(path6);
579
- const cmd = maxBytes !== void 0 ? ["head", "-c", String(maxBytes), resolved] : ["cat", resolved];
580
- const { exitCode, stdout, stderr } = await this.exec([
581
- "bash",
582
- "-c",
583
- `${cmd.map(shellEscape).join(" ")} | base64`
584
- ]);
585
- if (exitCode !== 0) {
586
- throw new Error(`DockerFs readFileBytes failed: ${stderr.trim() || `exit code ${exitCode}`}`);
587
- }
588
- return Buffer.from(stdout.trim(), "base64");
589
- }
590
- async writeFile(path6, content) {
591
- const resolved = this.resolvePath(path6);
592
- const dir = resolved.substring(0, resolved.lastIndexOf("/"));
593
- if (dir) {
594
- await this.exec(["mkdir", "-p", dir]);
595
- }
596
- const encoded = Buffer.from(content, "utf-8").toString("base64");
597
- const MAX_INLINE_LEN = 1e5;
598
- if (encoded.length <= MAX_INLINE_LEN) {
599
- const { exitCode, stderr } = await this.exec([
600
- "bash",
601
- "-c",
602
- `echo ${shellEscape(encoded)} | base64 -d > ${shellEscape(resolved)}`
603
- ]);
604
- if (exitCode !== 0) {
605
- throw new Error(`DockerFs writeFile failed: ${stderr.trim()}`);
606
- }
607
- } else {
608
- const execInstance = await this.container.exec({
609
- Cmd: ["bash", "-c", `base64 -d > ${shellEscape(resolved)}`],
610
- AttachStdout: true,
611
- AttachStderr: true,
612
- AttachStdin: true,
613
- Tty: false
614
- });
615
- const stream = await execInstance.start({ hijack: true, stdin: true });
616
- const writable = stream;
617
- writable.write(encoded);
618
- writable.end();
619
- const result = await collectExecStream(stream);
620
- const inspection = await execInstance.inspect();
621
- if (inspection.ExitCode !== 0) {
622
- throw new Error(`DockerFs writeFile failed: ${result.stderr.trim()}`);
623
- }
624
- }
625
- }
626
- async appendFile(path6, content) {
627
- const resolved = this.resolvePath(path6);
628
- const dir = resolved.substring(0, resolved.lastIndexOf("/"));
629
- if (dir) {
630
- await this.exec(["mkdir", "-p", dir]);
631
- }
632
- const encoded = Buffer.from(content, "utf-8").toString("base64");
633
- const { exitCode, stderr } = await this.exec([
634
- "bash",
635
- "-c",
636
- `echo ${shellEscape(encoded)} | base64 -d >> ${shellEscape(resolved)}`
637
- ]);
638
- if (exitCode !== 0) {
639
- throw new Error(`DockerFs appendFile failed: ${stderr.trim()}`);
640
- }
641
- }
642
- async deleteFile(path6, opts) {
643
- const resolved = this.resolvePath(path6);
644
- const args = opts?.recursive ? ["rm", "-rf", resolved] : ["rm", "-f", resolved];
645
- await this.exec(args);
646
- }
647
- async mkdir(path6, opts) {
648
- const resolved = this.resolvePath(path6);
649
- const args = opts?.recursive ? ["mkdir", "-p", resolved] : ["mkdir", resolved];
650
- await this.exec(args);
651
- }
652
- async readdir(path6, _opts) {
653
- const resolved = this.resolvePath(path6);
654
- const { exitCode, stdout, stderr } = await this.exec([
655
- "bash",
656
- "-c",
657
- `find ${shellEscape(resolved)} -maxdepth 1 -mindepth 1 -printf '%y %p\\n' 2>/dev/null`
658
- ]);
659
- if (exitCode !== 0 && stderr.trim()) {
660
- throw new Error(`DockerFs readdir failed: ${stderr.trim()}`);
661
- }
662
- const entries = [];
663
- for (const line of stdout.trim().split("\n")) {
664
- if (!line) continue;
665
- const spaceIdx = line.indexOf(" ");
666
- const type = line.substring(0, spaceIdx);
667
- const fullPath = line.substring(spaceIdx + 1);
668
- const name = fullPath.substring(fullPath.lastIndexOf("/") + 1);
669
- entries.push({
670
- name,
671
- path: fullPath,
672
- isDirectory: type === "d",
673
- isFile: type === "f"
674
- });
675
- }
676
- return entries;
677
- }
678
- async exists(path6) {
679
- const resolved = this.resolvePath(path6);
680
- const { exitCode } = await this.exec(["test", "-e", resolved]);
681
- return exitCode === 0;
682
- }
683
- async stat(path6) {
684
- const resolved = this.resolvePath(path6);
685
- const { exitCode, stdout, stderr } = await this.exec([
686
- "stat",
687
- "-c",
688
- "%s %F %W %Y",
689
- resolved
690
- ]);
691
- if (exitCode !== 0) {
692
- throw new Error(`DockerFs stat failed: ${stderr.trim() || `exit code ${exitCode}`}`);
693
- }
694
- const parts = stdout.trim().split(" ");
695
- const size = parseInt(parts[0], 10);
696
- const fileType = parts[1];
697
- const createdEpoch = parseInt(parts[2], 10);
698
- const modifiedEpoch = parseInt(parts[3], 10);
699
- return {
700
- size,
701
- isDirectory: fileType === "directory",
702
- isFile: fileType.startsWith("regular"),
703
- createdAt: createdEpoch > 0 ? new Date(createdEpoch * 1e3) : void 0,
704
- modifiedAt: modifiedEpoch > 0 ? new Date(modifiedEpoch * 1e3) : void 0
705
- };
706
- }
707
- };
708
- function shellEscape(s) {
709
- return `'${s.replace(/'/g, "'\\''")}'`;
710
- }
711
- function collectExecStream(stream) {
712
- return new Promise((resolve7, reject) => {
713
- const stdoutBufs = [];
714
- const stderrBufs = [];
715
- let pending = Buffer.alloc(0);
716
- stream.on("data", (chunk) => {
717
- let buf = pending.length > 0 ? Buffer.concat([pending, chunk]) : chunk;
718
- let offset = 0;
719
- while (offset + 8 <= buf.length) {
720
- const payloadLen = buf.readUInt32BE(offset + 4);
721
- if (offset + 8 + payloadLen > buf.length) break;
722
- const streamType = buf[offset];
723
- const payload = buf.subarray(offset + 8, offset + 8 + payloadLen);
724
- if (streamType === 2) {
725
- stderrBufs.push(payload);
726
- } else {
727
- stdoutBufs.push(payload);
728
- }
729
- offset += 8 + payloadLen;
730
- }
731
- pending = offset < buf.length ? buf.subarray(offset) : Buffer.alloc(0);
732
- });
733
- stream.on("end", () => {
734
- resolve7({
735
- stdout: Buffer.concat(stdoutBufs).toString("utf-8"),
736
- stderr: Buffer.concat(stderrBufs).toString("utf-8")
737
- });
738
- });
739
- stream.on("error", (err) => reject(err));
740
- });
741
- }
742
-
743
- // src/virtual/docker-computer.ts
744
- var DockerComputer = class {
745
- container;
746
- defaultCwd;
747
- defaultTimeout;
748
- constructor(opts) {
749
- this.container = opts.container;
750
- this.defaultCwd = opts.defaultCwd ?? "/";
751
- this.defaultTimeout = opts.defaultTimeout ?? 3e4;
752
- }
753
- async executeCommand(command, opts) {
754
- const cwd = opts?.cwd ?? this.defaultCwd;
755
- const timeout = opts?.timeout ?? this.defaultTimeout;
756
- const execOpts = {
757
- Cmd: ["bash", "-c", `cd ${shellEscape2(cwd)} && ${command}`],
758
- AttachStdout: true,
759
- AttachStderr: true,
760
- Tty: false
761
- };
762
- if (opts?.env) {
763
- execOpts.Env = Object.entries(opts.env).map(
764
- ([k, v]) => `${k}=${v}`
765
- );
766
- }
767
- const exec = await this.container.exec(execOpts);
768
- const stream = await exec.start({ hijack: true, stdin: false });
769
- const { stdout, stderr } = await collectStream(stream, timeout);
770
- const inspection = await exec.inspect();
771
- return {
772
- exitCode: inspection.ExitCode,
773
- stdout,
774
- stderr
775
- };
776
- }
777
- };
778
- function shellEscape2(s) {
779
- return `'${s.replace(/'/g, "'\\''")}'`;
780
- }
781
- function collectStream(stream, timeout) {
782
- return new Promise((resolve7, reject) => {
783
- const stdoutBufs = [];
784
- const stderrBufs = [];
785
- let pending = Buffer.alloc(0);
786
- const timer = setTimeout(() => {
787
- stream.destroy?.();
788
- resolve7({
789
- stdout: Buffer.concat(stdoutBufs).toString("utf-8"),
790
- stderr: Buffer.concat(stderrBufs).toString("utf-8") + "\n[timeout after " + timeout + "ms]"
791
- });
792
- }, timeout);
793
- stream.on("data", (chunk) => {
794
- let buf = pending.length > 0 ? Buffer.concat([pending, chunk]) : chunk;
795
- let offset = 0;
796
- while (offset + 8 <= buf.length) {
797
- const payloadLen = buf.readUInt32BE(offset + 4);
798
- if (offset + 8 + payloadLen > buf.length) break;
799
- const streamType = buf[offset];
800
- const payload = buf.subarray(offset + 8, offset + 8 + payloadLen);
801
- if (streamType === 2) {
802
- stderrBufs.push(payload);
803
- } else {
804
- stdoutBufs.push(payload);
805
- }
806
- offset += 8 + payloadLen;
807
- }
808
- pending = offset < buf.length ? buf.subarray(offset) : Buffer.alloc(0);
809
- });
810
- stream.on("end", () => {
811
- clearTimeout(timer);
812
- resolve7({
813
- stdout: Buffer.concat(stdoutBufs).toString("utf-8"),
814
- stderr: Buffer.concat(stderrBufs).toString("utf-8")
815
- });
816
- });
817
- stream.on("error", (err) => {
818
- clearTimeout(timer);
819
- reject(err);
820
- });
821
- });
822
- }
823
-
824
- // src/virtual/e2b-fs.ts
825
- import * as path4 from "path";
826
- var E2BFs = class {
827
- sandbox;
828
- workingDir;
829
- constructor(opts) {
830
- this.sandbox = opts.sandbox;
831
- this.workingDir = opts.workingDir;
832
- }
833
- resolvePath(p) {
834
- if (!this.workingDir) return p;
835
- const normalizedBase = this.workingDir.endsWith("/") ? this.workingDir : this.workingDir + "/";
836
- if (p.startsWith("/")) {
837
- if (p !== this.workingDir && !p.startsWith(normalizedBase)) {
838
- throw new Error(`Absolute path "${p}" is outside working directory "${this.workingDir}"`);
839
- }
840
- return p;
841
- }
842
- const resolved = path4.resolve(this.workingDir, p);
843
- if (resolved !== this.workingDir && !resolved.startsWith(normalizedBase)) {
844
- throw new Error(`Path "${p}" escapes working directory "${this.workingDir}"`);
845
- }
846
- return resolved;
847
- }
848
- async readFile(path6, _opts) {
849
- return this.sandbox.files.read(this.resolvePath(path6), {
850
- format: "text"
851
- });
852
- }
853
- async readFileBytes(path6, maxBytes) {
854
- const data = await this.sandbox.files.read(this.resolvePath(path6), {
855
- format: "bytes"
856
- });
857
- const buf = Buffer.from(data);
858
- if (maxBytes !== void 0 && buf.length > maxBytes) {
859
- return buf.subarray(0, maxBytes);
860
- }
861
- return buf;
862
- }
863
- async writeFile(path6, content) {
864
- await this.sandbox.files.write(this.resolvePath(path6), content);
865
- }
866
- /**
867
- * @warning Not atomic. Concurrent appends may lose data due to
868
- * read-then-write TOCTOU. The E2B SDK does not expose an append primitive.
869
- */
870
- async appendFile(path6, content) {
871
- let existing = "";
872
- try {
873
- existing = await this.readFile(path6);
874
- } catch {
875
- }
876
- await this.writeFile(path6, existing + content);
877
- }
878
- async deleteFile(path6, _opts) {
879
- await this.sandbox.files.remove(this.resolvePath(path6));
880
- }
881
- async mkdir(path6, _opts) {
882
- await this.sandbox.files.makeDir(this.resolvePath(path6));
883
- }
884
- async readdir(path6, _opts) {
885
- const entries = await this.sandbox.files.list(this.resolvePath(path6));
886
- return entries.map((entry) => ({
887
- name: entry.name,
888
- path: entry.path,
889
- isDirectory: entry.type === "dir",
890
- isFile: entry.type === "file",
891
- size: entry.size
892
- }));
893
- }
894
- async exists(path6) {
895
- return this.sandbox.files.exists(this.resolvePath(path6));
896
- }
897
- async stat(path6) {
898
- const info = await this.sandbox.files.getInfo(this.resolvePath(path6));
899
- return {
900
- size: info.size ?? 0,
901
- isDirectory: info.type === "dir",
902
- isFile: info.type === "file",
903
- modifiedAt: info.modifiedTime
904
- };
905
- }
906
- };
907
-
908
- // src/virtual/e2b-computer.ts
909
- var E2BComputer = class {
910
- sandbox;
911
- defaultCwd;
912
- defaultTimeout;
913
- constructor(opts) {
914
- this.sandbox = opts.sandbox;
915
- this.defaultCwd = opts.defaultCwd;
916
- this.defaultTimeout = opts.defaultTimeout ?? 3e4;
917
- }
918
- async executeCommand(command, opts) {
919
- const result = await this.sandbox.commands.run(command, {
920
- cwd: opts?.cwd ?? this.defaultCwd,
921
- timeout: opts?.timeout ?? this.defaultTimeout,
922
- envs: opts?.env
923
- });
924
- return {
925
- exitCode: result.exitCode,
926
- stdout: result.stdout ?? "",
927
- stderr: result.stderr ?? ""
928
- };
929
- }
930
- };
931
-
932
- // src/virtual/freestyle-fs.ts
933
- import * as path5 from "path";
934
- var FreestyleFs = class {
935
- vm;
936
- workingDir;
937
- constructor(opts) {
938
- this.vm = opts.vm;
939
- this.workingDir = opts.workingDir;
940
- }
941
- resolvePath(p) {
942
- if (p.includes("\0")) {
943
- throw new Error("Path contains null bytes");
944
- }
945
- if (!this.workingDir) return p;
946
- const normalizedBase = this.workingDir.endsWith("/") ? this.workingDir : this.workingDir + "/";
947
- if (p.startsWith("/")) {
948
- const normalized = path5.normalize(p);
949
- if (normalized !== this.workingDir && !normalized.startsWith(normalizedBase)) {
950
- throw new Error(`Absolute path "${p}" is outside working directory "${this.workingDir}"`);
951
- }
952
- return normalized;
953
- }
954
- const resolved = path5.resolve(this.workingDir, p);
955
- if (resolved !== this.workingDir && !resolved.startsWith(normalizedBase)) {
956
- throw new Error(`Path "${p}" escapes working directory "${this.workingDir}"`);
957
- }
958
- return resolved;
959
- }
960
- async readFile(filePath, _opts) {
961
- return this.vm.fs.readTextFile(this.resolvePath(filePath));
962
- }
963
- async readFileBytes(filePath, maxBytes) {
964
- const resolved = this.resolvePath(filePath);
965
- const cmd = maxBytes !== void 0 ? `head -c ${maxBytes} ${shellEscape3(resolved)} | base64` : `base64 ${shellEscape3(resolved)}`;
966
- const { statusCode, stdout, stderr } = await this.vm.exec(cmd);
967
- if (statusCode !== 0) {
968
- throw new Error(`FreestyleFs readFileBytes failed: ${stderr?.trim() || `exit code ${statusCode}`}`);
969
- }
970
- return Buffer.from((stdout ?? "").trim(), "base64");
971
- }
972
- async writeFile(filePath, content) {
973
- await this.vm.fs.writeTextFile(this.resolvePath(filePath), content);
974
- }
975
- async appendFile(filePath, content) {
976
- const resolved = this.resolvePath(filePath);
977
- const encoded = Buffer.from(content, "utf-8").toString("base64");
978
- const { statusCode, stderr } = await this.vm.exec(
979
- `echo ${shellEscape3(encoded)} | base64 -d >> ${shellEscape3(resolved)}`
980
- );
981
- if (statusCode !== 0) {
982
- throw new Error(`FreestyleFs appendFile failed: ${stderr?.trim() || `exit code ${statusCode}`}`);
983
- }
984
- }
985
- async deleteFile(filePath, opts) {
986
- const resolved = this.resolvePath(filePath);
987
- const flag = opts?.recursive ? "-rf" : "-f";
988
- await this.vm.exec(`rm ${flag} ${shellEscape3(resolved)}`);
989
- }
990
- async mkdir(filePath, opts) {
991
- const resolved = this.resolvePath(filePath);
992
- const flag = opts?.recursive ? "-p " : "";
993
- await this.vm.exec(`mkdir ${flag}${shellEscape3(resolved)}`);
994
- }
995
- async readdir(dirPath, _opts) {
996
- const resolved = this.resolvePath(dirPath);
997
- const items = await this.vm.fs.readDir(resolved);
998
- return items.map((entry) => ({
999
- name: entry.name,
1000
- path: resolved === "/" ? `/${entry.name}` : `${resolved}/${entry.name}`,
1001
- isDirectory: entry.kind === "dir" || entry.kind === "directory",
1002
- isFile: entry.kind === "file"
1003
- }));
1004
- }
1005
- async exists(filePath) {
1006
- const resolved = this.resolvePath(filePath);
1007
- const { statusCode } = await this.vm.exec(`test -e ${shellEscape3(resolved)}`);
1008
- return statusCode === 0;
1009
- }
1010
- async stat(filePath) {
1011
- const resolved = this.resolvePath(filePath);
1012
- const { statusCode, stdout, stderr } = await this.vm.exec(
1013
- `stat -c '%s %F %W %Y' ${shellEscape3(resolved)}`
1014
- );
1015
- if (statusCode !== 0) {
1016
- throw new Error(`FreestyleFs stat failed: ${stderr?.trim() || `exit code ${statusCode}`}`);
1017
- }
1018
- const parts = (stdout ?? "").trim().split(" ");
1019
- const size = parseInt(parts[0], 10);
1020
- const fileType = parts[1];
1021
- const createdEpoch = parseInt(parts[2], 10);
1022
- const modifiedEpoch = parseInt(parts[3], 10);
1023
- return {
1024
- size,
1025
- isDirectory: fileType === "directory",
1026
- isFile: fileType.startsWith("regular"),
1027
- createdAt: createdEpoch > 0 ? new Date(createdEpoch * 1e3) : void 0,
1028
- modifiedAt: modifiedEpoch > 0 ? new Date(modifiedEpoch * 1e3) : void 0
1029
- };
1030
- }
1031
- };
1032
- function shellEscape3(s) {
1033
- return `'${s.replace(/'/g, "'\\''")}'`;
1034
- }
1035
-
1036
- // src/virtual/freestyle-computer.ts
1037
- var FreestyleComputer = class {
1038
- vm;
1039
- defaultCwd;
1040
- defaultTimeout;
1041
- constructor(opts) {
1042
- this.vm = opts.vm;
1043
- this.defaultCwd = opts.defaultCwd;
1044
- this.defaultTimeout = opts.defaultTimeout ?? 3e4;
1045
- }
1046
- async executeCommand(command, opts) {
1047
- const result = await this.vm.exec(command, {
1048
- cwd: opts?.cwd ?? this.defaultCwd,
1049
- timeout: opts?.timeout ?? this.defaultTimeout
1050
- });
1051
- return {
1052
- exitCode: result.statusCode ?? 1,
1053
- stdout: result.stdout ?? "",
1054
- stderr: result.stderr ?? ""
1055
- };
1056
- }
1057
- };
1058
-
1059
286
  // src/virtual/sandbox.ts
1060
- function uninitError() {
1061
- throw new Error(
1062
- "Sandbox not initialized \u2014 call init() or pass a pre-created resource"
1063
- );
1064
- }
1065
- function createFsProxy() {
1066
- let inner = null;
1067
- const get = () => inner ?? uninitError();
1068
- return {
1069
- setTarget(target) {
1070
- inner = target;
1071
- },
1072
- readFile: (...args) => get().readFile(...args),
1073
- readFileBytes: (...args) => get().readFileBytes?.(...args),
1074
- writeFile: (...args) => get().writeFile(...args),
1075
- appendFile: (...args) => get().appendFile(...args),
1076
- deleteFile: (...args) => get().deleteFile(...args),
1077
- mkdir: (...args) => get().mkdir(...args),
1078
- readdir: (...args) => get().readdir(...args),
1079
- exists: (...args) => get().exists(...args),
1080
- stat: (...args) => get().stat(...args)
1081
- };
1082
- }
1083
- function createComputerProxy() {
1084
- let inner = null;
1085
- const get = () => inner ?? uninitError();
1086
- return {
1087
- setTarget(target) {
1088
- inner = target;
1089
- },
1090
- executeCommand: (...args) => get().executeCommand(...args)
1091
- };
1092
- }
1093
287
  function UnsandboxedLocal(opts) {
1094
288
  const cwd = opts?.cwd;
1095
289
  return {
@@ -1121,358 +315,6 @@ function LocalSandbox(opts) {
1121
315
  dispose: () => computer.dispose()
1122
316
  };
1123
317
  }
1124
- function SpritesSandbox(opts) {
1125
- const baseURL = (opts.baseURL ?? "https://api.sprites.dev").replace(/\/$/, "");
1126
- const userProvidedName = opts.spriteName;
1127
- if (userProvidedName) {
1128
- const fsOpts = { ...opts, spriteName: userProvidedName };
1129
- return {
1130
- fs: new SpritesFs(fsOpts),
1131
- computer: new SpritesComputer(fsOpts),
1132
- sandboxId: () => userProvidedName
1133
- };
1134
- }
1135
- const fsProxy = createFsProxy();
1136
- const computerProxy = createComputerProxy();
1137
- let resolvedName;
1138
- let autoCreated = false;
1139
- let initPromise = null;
1140
- async function doInit(reconnectId) {
1141
- let name = reconnectId ?? `${opts.namePrefix ?? "noumen-"}${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
1142
- let needsCreate = !reconnectId;
1143
- if (reconnectId) {
1144
- const check = await fetch(`${baseURL}/v1/sprites/${reconnectId}`, {
1145
- method: "GET",
1146
- headers: { Authorization: `Bearer ${opts.token}` }
1147
- });
1148
- if (!check.ok) {
1149
- name = `${opts.namePrefix ?? "noumen-"}${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
1150
- needsCreate = true;
1151
- }
1152
- }
1153
- if (needsCreate) {
1154
- const res = await fetch(`${baseURL}/v1/sprites`, {
1155
- method: "POST",
1156
- headers: {
1157
- Authorization: `Bearer ${opts.token}`,
1158
- "Content-Type": "application/json"
1159
- },
1160
- body: JSON.stringify({ name })
1161
- });
1162
- if (!res.ok) {
1163
- throw new Error(`Sprites auto-create failed (${res.status}): ${await res.text()}`);
1164
- }
1165
- autoCreated = true;
1166
- }
1167
- resolvedName = name;
1168
- const childOpts = { ...opts, spriteName: name };
1169
- fsProxy.setTarget(new SpritesFs(childOpts));
1170
- computerProxy.setTarget(new SpritesComputer(childOpts));
1171
- }
1172
- return {
1173
- fs: fsProxy,
1174
- computer: computerProxy,
1175
- sandboxId: () => resolvedName,
1176
- init(sandboxId) {
1177
- if (!initPromise) {
1178
- initPromise = doInit(sandboxId).catch((err) => {
1179
- initPromise = null;
1180
- throw err;
1181
- });
1182
- }
1183
- return initPromise;
1184
- },
1185
- async dispose() {
1186
- if (initPromise) {
1187
- await initPromise.catch(() => {
1188
- });
1189
- }
1190
- if (!autoCreated || !resolvedName) return;
1191
- try {
1192
- const res = await fetch(`${baseURL}/v1/sprites/${resolvedName}`, {
1193
- method: "DELETE",
1194
- headers: { Authorization: `Bearer ${opts.token}` }
1195
- });
1196
- if (!res.ok && res.status !== 404) {
1197
- throw new Error(`Sprites dispose failed (${res.status}): ${await res.text()}`);
1198
- }
1199
- } catch {
1200
- }
1201
- }
1202
- };
1203
- }
1204
- function DockerSandbox(opts) {
1205
- if (opts.container) {
1206
- const c = opts.container;
1207
- return {
1208
- fs: new DockerFs({ container: c, workingDir: opts.cwd }),
1209
- computer: new DockerComputer({
1210
- container: c,
1211
- defaultCwd: opts.cwd,
1212
- defaultTimeout: opts.defaultTimeout
1213
- }),
1214
- sandboxId: () => c.id
1215
- };
1216
- }
1217
- if (!opts.image) {
1218
- throw new Error("DockerSandbox requires either `container` or `image`");
1219
- }
1220
- const fsProxy = createFsProxy();
1221
- const computerProxy = createComputerProxy();
1222
- let containerId;
1223
- let containerRef;
1224
- let autoCreated = false;
1225
- let initPromise = null;
1226
- async function doInit(reconnectId) {
1227
- const Docker = (await import("dockerode")).default;
1228
- const docker = new Docker();
1229
- let container;
1230
- if (reconnectId) {
1231
- container = docker.getContainer(reconnectId);
1232
- try {
1233
- await container.inspect();
1234
- } catch {
1235
- container = await docker.createContainer({
1236
- Image: opts.image,
1237
- Cmd: opts.cmd ?? ["sleep", "infinity"],
1238
- Env: opts.env,
1239
- Tty: false,
1240
- ...opts.dockerOptions
1241
- });
1242
- await container.start();
1243
- autoCreated = true;
1244
- }
1245
- } else {
1246
- container = await docker.createContainer({
1247
- Image: opts.image,
1248
- Cmd: opts.cmd ?? ["sleep", "infinity"],
1249
- Env: opts.env,
1250
- Tty: false,
1251
- ...opts.dockerOptions
1252
- });
1253
- await container.start();
1254
- autoCreated = true;
1255
- }
1256
- containerRef = container;
1257
- containerId = container.id;
1258
- fsProxy.setTarget(new DockerFs({ container, workingDir: opts.cwd }));
1259
- computerProxy.setTarget(new DockerComputer({
1260
- container,
1261
- defaultCwd: opts.cwd,
1262
- defaultTimeout: opts.defaultTimeout
1263
- }));
1264
- }
1265
- return {
1266
- fs: fsProxy,
1267
- computer: computerProxy,
1268
- sandboxId: () => containerId,
1269
- init(sandboxId) {
1270
- if (!initPromise) {
1271
- initPromise = doInit(sandboxId).catch((err) => {
1272
- initPromise = null;
1273
- throw err;
1274
- });
1275
- }
1276
- return initPromise;
1277
- },
1278
- async dispose() {
1279
- if (initPromise) {
1280
- await initPromise.catch(() => {
1281
- });
1282
- }
1283
- if (!autoCreated || !containerRef) return;
1284
- try {
1285
- await containerRef.stop();
1286
- } catch {
1287
- }
1288
- try {
1289
- await containerRef.remove();
1290
- } catch {
1291
- }
1292
- }
1293
- };
1294
- }
1295
- function E2BSandbox(opts) {
1296
- if (opts.sandbox) {
1297
- const s = opts.sandbox;
1298
- return {
1299
- fs: new E2BFs({ sandbox: s, workingDir: opts.cwd }),
1300
- computer: new E2BComputer({
1301
- sandbox: s,
1302
- defaultCwd: opts.cwd,
1303
- defaultTimeout: opts.defaultTimeout
1304
- }),
1305
- sandboxId: () => s.sandboxId
1306
- };
1307
- }
1308
- const fsProxy = createFsProxy();
1309
- const computerProxy = createComputerProxy();
1310
- let resolvedId;
1311
- let sandboxRef;
1312
- let autoCreated = false;
1313
- let initPromise = null;
1314
- async function doInit(reconnectId) {
1315
- const e2b = await import("e2b");
1316
- const SandboxClass = e2b.Sandbox ?? e2b.default?.Sandbox;
1317
- if (!SandboxClass) {
1318
- throw new Error("Could not resolve Sandbox class from 'e2b' package");
1319
- }
1320
- let sandbox;
1321
- if (reconnectId) {
1322
- try {
1323
- sandbox = await SandboxClass.connect(reconnectId, {
1324
- apiKey: opts.apiKey
1325
- });
1326
- } catch {
1327
- sandbox = await SandboxClass.create({
1328
- template: opts.template ?? "base",
1329
- apiKey: opts.apiKey,
1330
- timeoutMs: opts.timeoutMs
1331
- });
1332
- autoCreated = true;
1333
- }
1334
- } else {
1335
- sandbox = await SandboxClass.create({
1336
- template: opts.template ?? "base",
1337
- apiKey: opts.apiKey,
1338
- timeoutMs: opts.timeoutMs
1339
- });
1340
- autoCreated = true;
1341
- }
1342
- sandboxRef = sandbox;
1343
- resolvedId = sandbox.sandboxId ?? reconnectId;
1344
- fsProxy.setTarget(new E2BFs({ sandbox, workingDir: opts.cwd }));
1345
- computerProxy.setTarget(new E2BComputer({
1346
- sandbox,
1347
- defaultCwd: opts.cwd,
1348
- defaultTimeout: opts.defaultTimeout
1349
- }));
1350
- }
1351
- return {
1352
- fs: fsProxy,
1353
- computer: computerProxy,
1354
- sandboxId: () => resolvedId,
1355
- init(sandboxId) {
1356
- if (!initPromise) {
1357
- initPromise = doInit(sandboxId).catch((err) => {
1358
- initPromise = null;
1359
- throw err;
1360
- });
1361
- }
1362
- return initPromise;
1363
- },
1364
- async dispose() {
1365
- if (initPromise) {
1366
- await initPromise.catch(() => {
1367
- });
1368
- }
1369
- if (!autoCreated || !sandboxRef) return;
1370
- if (typeof sandboxRef.kill === "function") {
1371
- await sandboxRef.kill();
1372
- }
1373
- }
1374
- };
1375
- }
1376
- function FreestyleSandbox(opts) {
1377
- if (opts.vm) {
1378
- const v = opts.vm;
1379
- return {
1380
- fs: new FreestyleFs({ vm: v, workingDir: opts.cwd }),
1381
- computer: new FreestyleComputer({
1382
- vm: v,
1383
- defaultCwd: opts.cwd,
1384
- defaultTimeout: opts.defaultTimeout
1385
- }),
1386
- sandboxId: () => v.vmId
1387
- };
1388
- }
1389
- const fsProxy = createFsProxy();
1390
- const computerProxy = createComputerProxy();
1391
- let resolvedId;
1392
- let vmRef = null;
1393
- let autoCreated = false;
1394
- let initPromise = null;
1395
- async function doInit(reconnectId) {
1396
- const mod = await import("freestyle-sandboxes");
1397
- const freestyle = mod.freestyle ?? mod.default?.freestyle;
1398
- if (!freestyle?.vms) {
1399
- throw new Error("Could not resolve freestyle client from 'freestyle-sandboxes' package");
1400
- }
1401
- let vm;
1402
- if (reconnectId) {
1403
- try {
1404
- const result = await freestyle.vms.get({ vmId: reconnectId });
1405
- vm = result.vm;
1406
- resolvedId = reconnectId;
1407
- } catch {
1408
- const result = await freestyle.vms.create({
1409
- ...opts.spec ? { spec: opts.spec } : {},
1410
- snapshotId: opts.snapshotId,
1411
- workdir: opts.cwd,
1412
- idleTimeoutSeconds: opts.idleTimeoutSeconds ?? 600,
1413
- additionalFiles: opts.additionalFiles,
1414
- gitRepos: opts.gitRepos
1415
- });
1416
- vm = result.vm;
1417
- resolvedId = result.vmId ?? result.id;
1418
- autoCreated = true;
1419
- }
1420
- } else {
1421
- const result = await freestyle.vms.create({
1422
- ...opts.spec ? { spec: opts.spec } : {},
1423
- snapshotId: opts.snapshotId,
1424
- workdir: opts.cwd,
1425
- idleTimeoutSeconds: opts.idleTimeoutSeconds ?? 600,
1426
- additionalFiles: opts.additionalFiles,
1427
- gitRepos: opts.gitRepos
1428
- });
1429
- vm = result.vm;
1430
- resolvedId = result.vmId ?? result.id;
1431
- autoCreated = true;
1432
- }
1433
- vmRef = vm;
1434
- fsProxy.setTarget(new FreestyleFs({ vm, workingDir: opts.cwd }));
1435
- computerProxy.setTarget(new FreestyleComputer({
1436
- vm,
1437
- defaultCwd: opts.cwd,
1438
- defaultTimeout: opts.defaultTimeout
1439
- }));
1440
- }
1441
- return {
1442
- fs: fsProxy,
1443
- computer: computerProxy,
1444
- sandboxId: () => resolvedId,
1445
- init(sandboxId) {
1446
- if (!initPromise) {
1447
- initPromise = doInit(sandboxId).catch((err) => {
1448
- initPromise = null;
1449
- throw err;
1450
- });
1451
- }
1452
- return initPromise;
1453
- },
1454
- async dispose() {
1455
- if (initPromise) {
1456
- await initPromise.catch(() => {
1457
- });
1458
- }
1459
- if (!autoCreated || !vmRef || !resolvedId) return;
1460
- try {
1461
- const strategy = opts.disposeStrategy ?? "suspend";
1462
- if (strategy === "suspend") {
1463
- await vmRef.suspend();
1464
- } else {
1465
- const mod = await import("freestyle-sandboxes");
1466
- const freestyle = mod.freestyle ?? mod.default?.freestyle;
1467
- if (freestyle?.vms) {
1468
- await freestyle.vms.delete({ vmId: resolvedId });
1469
- }
1470
- }
1471
- } catch {
1472
- }
1473
- }
1474
- };
1475
- }
1476
318
 
1477
319
  // src/checkpoint/manager.ts
1478
320
  import { createHash } from "crypto";
@@ -1704,8 +546,8 @@ var FileCheckpointManager = class {
1704
546
  restoreStateFromEntries(snapshots) {
1705
547
  const trackedFiles = /* @__PURE__ */ new Set();
1706
548
  for (const snap of snapshots) {
1707
- for (const path6 of Object.keys(snap.trackedFileBackups)) {
1708
- trackedFiles.add(path6);
549
+ for (const path2 of Object.keys(snap.trackedFileBackups)) {
550
+ trackedFiles.add(path2);
1709
551
  }
1710
552
  }
1711
553
  this.state = {
@@ -1719,7 +561,7 @@ var FileCheckpointManager = class {
1719
561
  // src/hooks/runner.ts
1720
562
  var DEFAULT_HOOK_TIMEOUT_MS = 3e4;
1721
563
  function withTimeout(promise, timeoutMs, label) {
1722
- return new Promise((resolve7, reject) => {
564
+ return new Promise((resolve3, reject) => {
1723
565
  const timer = setTimeout(
1724
566
  () => reject(new Error(`Hook "${label}" timed out after ${timeoutMs}ms`)),
1725
567
  timeoutMs
@@ -1727,7 +569,7 @@ function withTimeout(promise, timeoutMs, label) {
1727
569
  promise.then(
1728
570
  (v) => {
1729
571
  clearTimeout(timer);
1730
- resolve7(v);
572
+ resolve3(v);
1731
573
  },
1732
574
  (e) => {
1733
575
  clearTimeout(timer);
@@ -2991,10 +1833,10 @@ var SessionStorage = class {
2991
1833
  }
2992
1834
  }
2993
1835
  async loadMessages(sessionId) {
2994
- const path6 = this.getTranscriptPath(sessionId);
2995
- const exists = await this.fs.exists(path6);
1836
+ const path2 = this.getTranscriptPath(sessionId);
1837
+ const exists = await this.fs.exists(path2);
2996
1838
  if (!exists) return [];
2997
- const content = await this.fs.readFile(path6);
1839
+ const content = await this.fs.readFile(path2);
2998
1840
  const entries = parseJSONL(content);
2999
1841
  let lastBoundaryIdx = -1;
3000
1842
  for (let i = entries.length - 1; i >= 0; i--) {
@@ -3029,10 +1871,10 @@ var SessionStorage = class {
3029
1871
  return messages;
3030
1872
  }
3031
1873
  async loadAllEntries(sessionId) {
3032
- const path6 = this.getTranscriptPath(sessionId);
3033
- const exists = await this.fs.exists(path6);
1874
+ const path2 = this.getTranscriptPath(sessionId);
1875
+ const exists = await this.fs.exists(path2);
3034
1876
  if (!exists) return [];
3035
- const content = await this.fs.readFile(path6);
1877
+ const content = await this.fs.readFile(path2);
3036
1878
  return parseJSONL(content);
3037
1879
  }
3038
1880
  async sessionExists(sessionId) {
@@ -3402,17 +2244,17 @@ function walkAncestors(cwd) {
3402
2244
  }
3403
2245
  return dirs;
3404
2246
  }
3405
- async function tryLoadFile(fs2, path6, scope, out, maxDepth, excludes) {
3406
- if (isExcluded(path6, excludes)) return;
3407
- const file = await loadContextFile(fs2, path6, scope, /* @__PURE__ */ new Set(), 0, maxDepth);
2247
+ async function tryLoadFile(fs2, path2, scope, out, maxDepth, excludes) {
2248
+ if (isExcluded(path2, excludes)) return;
2249
+ const file = await loadContextFile(fs2, path2, scope, /* @__PURE__ */ new Set(), 0, maxDepth);
3408
2250
  if (file) out.push(file);
3409
2251
  }
3410
- async function loadContextFile(fs2, path6, scope, visited, depth, maxDepth) {
3411
- const normalized = normalizePath(path6);
2252
+ async function loadContextFile(fs2, path2, scope, visited, depth, maxDepth) {
2253
+ const normalized = normalizePath(path2);
3412
2254
  if (visited.has(normalized)) return null;
3413
2255
  let raw;
3414
2256
  try {
3415
- raw = await fs2.readFile(path6);
2257
+ raw = await fs2.readFile(path2);
3416
2258
  } catch {
3417
2259
  return null;
3418
2260
  }
@@ -3421,9 +2263,9 @@ async function loadContextFile(fs2, path6, scope, visited, depth, maxDepth) {
3421
2263
  const { frontmatter, body } = parseFrontmatter(raw);
3422
2264
  const globs = parsePaths(frontmatter.paths);
3423
2265
  const content = stripHtmlComments(body);
3424
- const includes = await resolveIncludes(fs2, content, path6, visited, depth, maxDepth);
2266
+ const includes = await resolveIncludes(fs2, content, path2, visited, depth, maxDepth);
3425
2267
  return {
3426
- path: path6,
2268
+ path: path2,
3427
2269
  scope,
3428
2270
  content,
3429
2271
  ...globs.length > 0 ? { globs } : {},
@@ -3489,15 +2331,15 @@ function stripHtmlComments(content) {
3489
2331
  if (!content.includes("<!--")) return content;
3490
2332
  return content.replace(/<!--[\s\S]*?-->/g, "");
3491
2333
  }
3492
- function isExcluded(path6, excludes) {
2334
+ function isExcluded(path2, excludes) {
3493
2335
  if (excludes.length === 0) return false;
3494
2336
  return excludes.some((pattern) => {
3495
- if (path6 === pattern) return true;
2337
+ if (path2 === pattern) return true;
3496
2338
  if (pattern.includes("*")) {
3497
2339
  const regex = simpleGlobToRegex(pattern);
3498
- return regex.test(path6);
2340
+ return regex.test(path2);
3499
2341
  }
3500
- return path6.includes(pattern);
2342
+ return path2.includes(pattern);
3501
2343
  });
3502
2344
  }
3503
2345
  function simpleGlobToRegex(glob) {
@@ -6231,7 +5073,7 @@ async function executeToolsStep(toolCalls, streamingExec, streamingResults, exec
6231
5073
  }
6232
5074
 
6233
5075
  // src/file-state/cache.ts
6234
- import { normalize as normalize4 } from "path";
5076
+ import { normalize as normalize2 } from "path";
6235
5077
  var DEFAULT_MAX_ENTRIES = 100;
6236
5078
  var DEFAULT_MAX_BYTES = 25 * 1024 * 1024;
6237
5079
  var FileStateCache = class {
@@ -6243,14 +5085,14 @@ var FileStateCache = class {
6243
5085
  this.maxEntries = config?.maxEntries ?? DEFAULT_MAX_ENTRIES;
6244
5086
  this.maxBytes = config?.maxBytes ?? DEFAULT_MAX_BYTES;
6245
5087
  }
6246
- key(path6) {
6247
- return normalize4(path6);
5088
+ key(path2) {
5089
+ return normalize2(path2);
6248
5090
  }
6249
5091
  byteSize(state) {
6250
5092
  return Math.max(1, Buffer.byteLength(state.content, "utf8"));
6251
5093
  }
6252
- set(path6, state) {
6253
- const k = this.key(path6);
5094
+ set(path2, state) {
5095
+ const k = this.key(path2);
6254
5096
  const existing = this.entries.get(k);
6255
5097
  if (existing) {
6256
5098
  this.currentBytes -= this.byteSize(existing);
@@ -6266,19 +5108,19 @@ var FileStateCache = class {
6266
5108
  this.entries.set(k, state);
6267
5109
  this.currentBytes += size;
6268
5110
  }
6269
- get(path6) {
6270
- const k = this.key(path6);
5111
+ get(path2) {
5112
+ const k = this.key(path2);
6271
5113
  const state = this.entries.get(k);
6272
5114
  if (!state) return void 0;
6273
5115
  this.entries.delete(k);
6274
5116
  this.entries.set(k, state);
6275
5117
  return state;
6276
5118
  }
6277
- has(path6) {
6278
- return this.entries.has(this.key(path6));
5119
+ has(path2) {
5120
+ return this.entries.has(this.key(path2));
6279
5121
  }
6280
- delete(path6) {
6281
- const k = this.key(path6);
5122
+ delete(path2) {
5123
+ const k = this.key(path2);
6282
5124
  const existing = this.entries.get(k);
6283
5125
  if (existing) {
6284
5126
  this.currentBytes -= this.byteSize(existing);
@@ -6320,8 +5162,8 @@ function getActiveSkills(allSkills, activatedNames) {
6320
5162
  return activatedNames.has(skill.name);
6321
5163
  });
6322
5164
  }
6323
- function matchesAnyGlob(path6, patterns) {
6324
- return patterns.some((pattern) => globMatch(pattern, path6));
5165
+ function matchesAnyGlob(path2, patterns) {
5166
+ return patterns.some((pattern) => globMatch(pattern, path2));
6325
5167
  }
6326
5168
  function globMatch(pattern, str) {
6327
5169
  const regex = globToRegex(pattern);
@@ -6803,8 +5645,8 @@ var StreamingToolExecutor = class {
6803
5645
  }
6804
5646
  if (this.hasExecuting() && !this.hasCompleted()) {
6805
5647
  const executingPromises = this.tools.filter((t) => t.status === "executing" && t.promise).map((t) => t.promise);
6806
- const progressPromise = new Promise((resolve7) => {
6807
- this.progressResolve = resolve7;
5648
+ const progressPromise = new Promise((resolve3) => {
5649
+ this.progressResolve = resolve3;
6808
5650
  });
6809
5651
  if (executingPromises.length > 0) {
6810
5652
  await Promise.race([...executingPromises, progressPromise]);
@@ -6847,7 +5689,7 @@ function getRetryDelay(attempt, retryAfterHeader, maxDelayMs = 32e3, baseDelayMs
6847
5689
  return baseDelay + jitter;
6848
5690
  }
6849
5691
  function sleep(ms, signal) {
6850
- return new Promise((resolve7, reject) => {
5692
+ return new Promise((resolve3, reject) => {
6851
5693
  if (signal?.aborted) {
6852
5694
  reject(new DOMException("Aborted", "AbortError"));
6853
5695
  return;
@@ -6858,7 +5700,7 @@ function sleep(ms, signal) {
6858
5700
  };
6859
5701
  const timer = setTimeout(() => {
6860
5702
  signal?.removeEventListener("abort", onAbort);
6861
- resolve7();
5703
+ resolve3();
6862
5704
  }, ms);
6863
5705
  signal?.addEventListener("abort", onAbort, { once: true });
6864
5706
  });
@@ -9216,7 +8058,7 @@ var Agent = class {
9216
8058
  if (this.resolvedProvider) return this.resolvedProvider;
9217
8059
  if (!this.providerPromise) {
9218
8060
  this.providerPromise = (async () => {
9219
- const { resolveProvider: resolveProvider2 } = await import("./resolve-4JA2BBDA.js");
8061
+ const { resolveProvider: resolveProvider2 } = await import("./resolve-GDSHNMG6.js");
9220
8062
  return resolveProvider2(this.providerInput, { model: this.model });
9221
8063
  })();
9222
8064
  }
@@ -10161,18 +9003,18 @@ var FileMemoryProvider = class {
10161
9003
  return "";
10162
9004
  }
10163
9005
  }
10164
- async loadEntry(path6) {
10165
- const fullPath = path6.startsWith(this.dir) ? path6 : this.dir + path6;
9006
+ async loadEntry(path2) {
9007
+ const fullPath = path2.startsWith(this.dir) ? path2 : this.dir + path2;
10166
9008
  try {
10167
9009
  const raw = await this.fs.readFile(fullPath);
10168
9010
  const fm = parseFrontmatter2(raw);
10169
9011
  const stat2 = await this.fs.stat(fullPath).catch(() => null);
10170
9012
  return {
10171
- name: fm.name ?? pathToName(path6),
9013
+ name: fm.name ?? pathToName(path2),
10172
9014
  description: fm.description ?? "",
10173
9015
  type: fm.type ?? "project",
10174
9016
  content: fm.rest,
10175
- path: path6.startsWith(this.dir) ? path6.slice(this.dir.length) : path6,
9017
+ path: path2.startsWith(this.dir) ? path2.slice(this.dir.length) : path2,
10176
9018
  updatedAt: stat2?.modifiedAt?.toISOString()
10177
9019
  };
10178
9020
  } catch {
@@ -10187,8 +9029,8 @@ var FileMemoryProvider = class {
10187
9029
  await this.fs.writeFile(fullPath, content);
10188
9030
  await this.rebuildIndex();
10189
9031
  }
10190
- async removeEntry(path6) {
10191
- const fullPath = path6.startsWith(this.dir) ? path6 : this.dir + path6;
9032
+ async removeEntry(path2) {
9033
+ const fullPath = path2.startsWith(this.dir) ? path2 : this.dir + path2;
10192
9034
  try {
10193
9035
  await this.fs.deleteFile(fullPath);
10194
9036
  } catch {
@@ -10237,20 +9079,8 @@ export {
10237
9079
  LocalFs,
10238
9080
  LocalComputer,
10239
9081
  SandboxedLocalComputer,
10240
- SpritesFs,
10241
- SpritesComputer,
10242
- DockerFs,
10243
- DockerComputer,
10244
- E2BFs,
10245
- E2BComputer,
10246
- FreestyleFs,
10247
- FreestyleComputer,
10248
9082
  UnsandboxedLocal,
10249
9083
  LocalSandbox,
10250
- SpritesSandbox,
10251
- DockerSandbox,
10252
- E2BSandbox,
10253
- FreestyleSandbox,
10254
9084
  createCheckpointState,
10255
9085
  FileCheckpointManager,
10256
9086
  runPreToolUseHooks,
@@ -10362,4 +9192,4 @@ export {
10362
9192
  truncateIndex,
10363
9193
  FileMemoryProvider
10364
9194
  };
10365
- //# sourceMappingURL=chunk-4HW6LN6D.js.map
9195
+ //# sourceMappingURL=chunk-WPCYGZOE.js.map