@amends-dev/sandbox-e2b 0.0.0-stage → 0.1.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.
- package/E2bSandboxProvider.d.ts +63 -0
- package/E2bSandboxProvider.d.ts.map +1 -0
- package/E2bSandboxProvider.js +156 -0
- package/E2bSandboxProvider.js.map +1 -0
- package/LICENSE +21 -0
- package/README.md +99 -2
- package/index.d.ts +10 -0
- package/index.d.ts.map +1 -0
- package/index.js +11 -0
- package/index.js.map +1 -0
- package/internal/call.d.ts +13 -0
- package/internal/call.d.ts.map +1 -0
- package/internal/call.js +66 -0
- package/internal/call.js.map +1 -0
- package/internal/files.d.ts +12 -0
- package/internal/files.d.ts.map +1 -0
- package/internal/files.js +178 -0
- package/internal/files.js.map +1 -0
- package/internal/network.d.ts +17 -0
- package/internal/network.d.ts.map +1 -0
- package/internal/network.js +12 -0
- package/internal/network.js.map +1 -0
- package/internal/processes.d.ts +30 -0
- package/internal/processes.d.ts.map +1 -0
- package/internal/processes.js +238 -0
- package/internal/processes.js.map +1 -0
- package/internal/shell.d.ts +3 -0
- package/internal/shell.d.ts.map +1 -0
- package/internal/shell.js +3 -0
- package/internal/shell.js.map +1 -0
- package/package.json +36 -4
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2B sandboxes, resumed through provider-owned metadata and stopped with filesystem-only
|
|
3
|
+
* persistence so processes do not return on resume. E2B assigns its own machine IDs; logical
|
|
4
|
+
* IDs are metadata, not an atomic distributed name reservation. See the package README.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.1.0
|
|
7
|
+
*/
|
|
8
|
+
import { Sandbox, SandboxError, SandboxProvider } from "@amends-dev/sandbox";
|
|
9
|
+
import * as Crypto from "effect/Crypto";
|
|
10
|
+
import * as Effect from "effect/Effect";
|
|
11
|
+
import * as Layer from "effect/Layer";
|
|
12
|
+
import * as Redacted from "effect/Redacted";
|
|
13
|
+
import * as Schema from "effect/Schema";
|
|
14
|
+
/**
|
|
15
|
+
* Connection settings and defaults for machines created by this provider.
|
|
16
|
+
*
|
|
17
|
+
* @category options
|
|
18
|
+
* @since 0.1.0
|
|
19
|
+
*/
|
|
20
|
+
export interface Options {
|
|
21
|
+
readonly apiKey: Redacted.Redacted<string>;
|
|
22
|
+
readonly apiUrl?: string;
|
|
23
|
+
readonly domain?: string;
|
|
24
|
+
/** E2B template or snapshot ID; defaults to E2B's base image. */
|
|
25
|
+
readonly template?: string;
|
|
26
|
+
/** E2B's running lifetime; defaults to one hour, then pauses with files preserved. */
|
|
27
|
+
readonly timeoutMs?: number;
|
|
28
|
+
readonly requestTimeoutMs?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Overrides under `providerOptions.e2b`. Invalid options fail before any allocation.
|
|
32
|
+
*
|
|
33
|
+
* @category options
|
|
34
|
+
* @since 0.1.0
|
|
35
|
+
*/
|
|
36
|
+
export declare const ProviderOptions: Schema.Struct<{
|
|
37
|
+
readonly template: Schema.optionalKey<Schema.String>;
|
|
38
|
+
readonly timeoutMs: Schema.optionalKey<Schema.Int>;
|
|
39
|
+
}>;
|
|
40
|
+
/** @category options
|
|
41
|
+
* @since 0.1.0
|
|
42
|
+
*/
|
|
43
|
+
export type ProviderOptions = typeof ProviderOptions.Type;
|
|
44
|
+
/**
|
|
45
|
+
* Constructs the provider using Effect's Crypto service for generated logical IDs.
|
|
46
|
+
* Templates prepare each sandbox before its requested network policy is applied.
|
|
47
|
+
*
|
|
48
|
+
* @category constructors
|
|
49
|
+
* @since 0.1.0
|
|
50
|
+
*/
|
|
51
|
+
export declare const make: (options: Options) => Effect.Effect<{
|
|
52
|
+
readonly create: <E = never>(options?: SandboxProvider.CreateOptions<E>) => Effect.Effect<Sandbox.Sandbox["Service"], SandboxError.SandboxError | E>;
|
|
53
|
+
readonly createScoped: <E = never>(options?: SandboxProvider.CreateOptions<E>) => Effect.Effect<Sandbox.Sandbox["Service"], SandboxError.SandboxError | E, import("effect/Scope").Scope>;
|
|
54
|
+
readonly resume: (id: Sandbox.SandboxId) => Effect.Effect<Sandbox.Sandbox["Service"], SandboxError.SandboxError>;
|
|
55
|
+
}, never, Crypto.Crypto>;
|
|
56
|
+
/**
|
|
57
|
+
* Provides sandboxes through E2B using `make`.
|
|
58
|
+
*
|
|
59
|
+
* @category layers
|
|
60
|
+
* @since 0.1.0
|
|
61
|
+
*/
|
|
62
|
+
export declare const layer: (options: Options) => Layer.Layer<SandboxProvider.SandboxProvider, never, Crypto.Crypto>;
|
|
63
|
+
//# sourceMappingURL=E2bSandboxProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"E2bSandboxProvider.d.ts","sourceRoot":"","sources":["../src/E2bSandboxProvider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAW,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErF,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAOvC;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,sFAAsF;IACtF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACnC;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe;;;EAG1B,CAAA;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA;AAOzD;;;;;;GAMG;AACH,eAAO,MAAM,IAAI;;;;wBA2Kf,CAAA;AAEF;;;;;GAKG;AACH,eAAO,MAAM,KAAK,YAAa,OAAO,uEAAiE,CAAA"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2B sandboxes, resumed through provider-owned metadata and stopped with filesystem-only
|
|
3
|
+
* persistence so processes do not return on resume. E2B assigns its own machine IDs; logical
|
|
4
|
+
* IDs are metadata, not an atomic distributed name reservation. See the package README.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.1.0
|
|
7
|
+
*/
|
|
8
|
+
import { Network, Sandbox, SandboxError, SandboxProvider } from "@amends-dev/sandbox";
|
|
9
|
+
import { Sandbox as E2bSandbox } from "e2b";
|
|
10
|
+
import * as Crypto from "effect/Crypto";
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import * as Exit from "effect/Exit";
|
|
13
|
+
import * as Layer from "effect/Layer";
|
|
14
|
+
import * as Redacted from "effect/Redacted";
|
|
15
|
+
import * as Schema from "effect/Schema";
|
|
16
|
+
import * as Semaphore from "effect/Semaphore";
|
|
17
|
+
import { call, providerId, sandboxError } from "./internal/call.js";
|
|
18
|
+
import { makeFileSystem } from "./internal/files.js";
|
|
19
|
+
import { networkSettingsOf } from "./internal/network.js";
|
|
20
|
+
import { makeChildProcessSpawner } from "./internal/processes.js";
|
|
21
|
+
/**
|
|
22
|
+
* Overrides under `providerOptions.e2b`. Invalid options fail before any allocation.
|
|
23
|
+
*
|
|
24
|
+
* @category options
|
|
25
|
+
* @since 0.1.0
|
|
26
|
+
*/
|
|
27
|
+
export const ProviderOptions = Schema.Struct({
|
|
28
|
+
template: Schema.optionalKey(Schema.String.check(Schema.isMinLength(1))),
|
|
29
|
+
timeoutMs: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThan(0)))
|
|
30
|
+
});
|
|
31
|
+
const ownerKey = "amends-provider";
|
|
32
|
+
const idKey = "amends-id";
|
|
33
|
+
const creationKey = "amends-creation";
|
|
34
|
+
const portDirectory = "/var/tmp/amends/ports";
|
|
35
|
+
/**
|
|
36
|
+
* Constructs the provider using Effect's Crypto service for generated logical IDs.
|
|
37
|
+
* Templates prepare each sandbox before its requested network policy is applied.
|
|
38
|
+
*
|
|
39
|
+
* @category constructors
|
|
40
|
+
* @since 0.1.0
|
|
41
|
+
*/
|
|
42
|
+
export const make = Effect.fnUntraced(function* (options) {
|
|
43
|
+
const crypto = yield* Crypto.Crypto;
|
|
44
|
+
const creates = yield* Semaphore.make(1);
|
|
45
|
+
const connection = {
|
|
46
|
+
apiKey: Redacted.value(options.apiKey),
|
|
47
|
+
// Explicit defaults avoid ambient SDK configuration changing which account endpoint is used.
|
|
48
|
+
apiUrl: options.apiUrl ?? `https://api.${options.domain ?? "e2b.app"}`,
|
|
49
|
+
domain: options.domain ?? "e2b.app",
|
|
50
|
+
debug: false,
|
|
51
|
+
retries: 0,
|
|
52
|
+
...(options.requestTimeoutMs === undefined ? {} : { requestTimeoutMs: options.requestTimeoutMs })
|
|
53
|
+
};
|
|
54
|
+
const findSandboxes = Effect.fnUntraced(function* (id, creation) {
|
|
55
|
+
const paginator = E2bSandbox.list({
|
|
56
|
+
...connection,
|
|
57
|
+
query: {
|
|
58
|
+
metadata: {
|
|
59
|
+
[ownerKey]: providerId,
|
|
60
|
+
[idKey]: id,
|
|
61
|
+
...(creation === undefined ? {} : { [creationKey]: creation })
|
|
62
|
+
},
|
|
63
|
+
state: ["running", "paused"]
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
const found = [];
|
|
67
|
+
while (paginator.hasNext)
|
|
68
|
+
found.push(...(yield* call(() => paginator.nextItems())));
|
|
69
|
+
return found;
|
|
70
|
+
});
|
|
71
|
+
const openSandbox = Effect.fnUntraced(function* (sandbox, id) {
|
|
72
|
+
const workingDirectory = (yield* call(() => sandbox.commands.run("pwd -P"))).stdout.trim();
|
|
73
|
+
const fileSystem = makeFileSystem(sandbox, workingDirectory);
|
|
74
|
+
const exposePorts = (ports) => Effect.forEach(ports, (port) => call(() => sandbox.files.write(`${portDirectory}/${port}`, "")), {
|
|
75
|
+
discard: true
|
|
76
|
+
});
|
|
77
|
+
return Sandbox.Sandbox.of({
|
|
78
|
+
id,
|
|
79
|
+
workingDirectory,
|
|
80
|
+
fileSystem,
|
|
81
|
+
childProcessSpawner: yield* makeChildProcessSpawner(sandbox, workingDirectory).pipe(Effect.provideService(Crypto.Crypto, crypto)),
|
|
82
|
+
exposePorts,
|
|
83
|
+
endpoint: (port, protocol) => Effect.flatMap(call(() => sandbox.files.exists(`${portDirectory}/${port}`)), (exposed) => exposed
|
|
84
|
+
? Effect.succeed({
|
|
85
|
+
url: `${protocol === "ws" ? "wss" : "https"}://${sandbox.getHost(port)}`,
|
|
86
|
+
headers: sandbox.trafficAccessToken === undefined
|
|
87
|
+
? {}
|
|
88
|
+
: { "e2b-traffic-access-token": Redacted.make(sandbox.trafficAccessToken) }
|
|
89
|
+
})
|
|
90
|
+
: Effect.fail(sandboxError(new SandboxError.NotFoundError({ description: `Port ${port} is not exposed` })))),
|
|
91
|
+
stop: Effect.flatMap(call(() => sandbox.getInfo()), (info) => info.state === "paused" ? Effect.void : Effect.asVoid(call(() => sandbox.pause({ mode: "filesystem" })))),
|
|
92
|
+
destroy: Effect.asVoid(call(() => sandbox.kill())).pipe(Effect.catchReason("SandboxError", "NotFoundError", () => Effect.void)),
|
|
93
|
+
setNetworkPolicy: (policy) => Effect.flatMap(networkSettingsOf(policy), (settings) => call(() => sandbox.updateNetwork(settings))),
|
|
94
|
+
setRequestTransformations: () => Effect.fail(sandboxError(new SandboxError.UnsupportedError({
|
|
95
|
+
description: "E2B's host-only transformations cannot enforce request path and header matching"
|
|
96
|
+
})))
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
const create = Effect.fn("E2bSandboxProvider.create")(function* (createOptions = {}) {
|
|
100
|
+
const providerOptions = yield* Schema.decodeUnknownEffect(ProviderOptions)(createOptions.providerOptions?.[providerId] ?? {}, { onExcessProperty: "error" }).pipe(Effect.mapError((error) => sandboxError(new SandboxError.InvalidOptionsError({ description: error.message }))));
|
|
101
|
+
const policy = yield* networkSettingsOf(createOptions.networkPolicy ?? Network.NetworkPolicy.cases.AllowAll.make({}));
|
|
102
|
+
const id = createOptions.id ??
|
|
103
|
+
Sandbox.SandboxId.make(yield* crypto.randomUUIDv4.pipe(Effect.mapError((error) => sandboxError(new SandboxError.UnknownError({ description: error.message })))));
|
|
104
|
+
if ((yield* findSandboxes(id)).length > 0) {
|
|
105
|
+
return yield* sandboxError(new SandboxError.AlreadyExistsError({ description: `Sandbox ${id} already exists` }));
|
|
106
|
+
}
|
|
107
|
+
const template = providerOptions.template ?? options.template;
|
|
108
|
+
const creation = yield* crypto.randomUUIDv4.pipe(Effect.mapError((error) => sandboxError(new SandboxError.UnknownError({ description: error.message }))));
|
|
109
|
+
return yield* Effect.acquireUseRelease(call(() => E2bSandbox.create({
|
|
110
|
+
...connection,
|
|
111
|
+
...(template === undefined ? {} : { template }),
|
|
112
|
+
timeoutMs: providerOptions.timeoutMs ?? options.timeoutMs ?? 3_600_000,
|
|
113
|
+
metadata: { [ownerKey]: providerId, [idKey]: id, [creationKey]: creation },
|
|
114
|
+
lifecycle: { onTimeout: { action: "pause", mode: "filesystem" }, autoResume: false },
|
|
115
|
+
network: { allowPublicTraffic: false, ...(createOptions.template === undefined ? policy : {}) }
|
|
116
|
+
})).pipe(
|
|
117
|
+
// A failed response can still have allocated. Locate only this attempt, never a rival's ID.
|
|
118
|
+
Effect.tapError(() => findSandboxes(id, creation).pipe(Effect.flatMap((allocated) => Effect.forEach(allocated, (sandbox) => call(() => E2bSandbox.kill(sandbox.sandboxId, connection)), {
|
|
119
|
+
discard: true
|
|
120
|
+
})), Effect.ignore))), (sandbox) => Effect.gen(function* () {
|
|
121
|
+
// Only this call's machine is cleaned up on failure. Never delete a competing creator's.
|
|
122
|
+
const matches = yield* findSandboxes(id);
|
|
123
|
+
if (matches.some((other) => other.sandboxId !== sandbox.sandboxId)) {
|
|
124
|
+
return yield* sandboxError(new SandboxError.AlreadyExistsError({ description: `Another host created sandbox ${id} concurrently` }));
|
|
125
|
+
}
|
|
126
|
+
const opened = yield* openSandbox(sandbox, id);
|
|
127
|
+
yield* opened.exposePorts(createOptions.ports ?? []);
|
|
128
|
+
if (createOptions.template !== undefined) {
|
|
129
|
+
yield* createOptions.template.prepare.pipe(Effect.provide(Sandbox.layerServices(opened)));
|
|
130
|
+
yield* call(() => sandbox.updateNetwork(policy));
|
|
131
|
+
}
|
|
132
|
+
return opened;
|
|
133
|
+
}), (sandbox, exit) => (Exit.isSuccess(exit) ? Effect.void : Effect.orDie(call(() => sandbox.kill()))));
|
|
134
|
+
}, (effect) => creates.withPermit(effect));
|
|
135
|
+
const resume = Effect.fn("E2bSandboxProvider.resume")(function* (id) {
|
|
136
|
+
const matches = yield* findSandboxes(id);
|
|
137
|
+
if (matches.length > 1) {
|
|
138
|
+
return yield* sandboxError(new SandboxError.UnknownError({ description: `Conflicting E2B machines claim logical sandbox ${id}` }));
|
|
139
|
+
}
|
|
140
|
+
const info = matches[0];
|
|
141
|
+
if (info === undefined) {
|
|
142
|
+
return yield* sandboxError(new SandboxError.NotFoundError({ description: `Sandbox ${id} does not exist` }));
|
|
143
|
+
}
|
|
144
|
+
const sandbox = yield* call(() => E2bSandbox.connect(info.sandboxId, { ...connection, timeoutMs: options.timeoutMs ?? 3_600_000 }));
|
|
145
|
+
return yield* openSandbox(sandbox, id);
|
|
146
|
+
});
|
|
147
|
+
return SandboxProvider.make({ create, resume });
|
|
148
|
+
});
|
|
149
|
+
/**
|
|
150
|
+
* Provides sandboxes through E2B using `make`.
|
|
151
|
+
*
|
|
152
|
+
* @category layers
|
|
153
|
+
* @since 0.1.0
|
|
154
|
+
*/
|
|
155
|
+
export const layer = (options) => Layer.effect(SandboxProvider.SandboxProvider, make(options));
|
|
156
|
+
//# sourceMappingURL=E2bSandboxProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"E2bSandboxProvider.js","sourceRoot":"","sources":["../src/E2bSandboxProvider.ts"],"names":[],"mappings":"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"}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sarib Mahmood
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,100 @@
|
|
|
1
|
-
#
|
|
1
|
+
# E2B sandbox provider
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@amends-dev/sandbox-e2b` implements the [sandbox contract](../../packages/sandbox/README.md)
|
|
4
|
+
with E2B's TypeScript SDK. Hosts install this adapter; shared packages depend only on the contract.
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import { E2bSandboxProvider } from "@amends-dev/sandbox-e2b"
|
|
8
|
+
import { BunCrypto } from "@effect/platform-bun"
|
|
9
|
+
import { Config, Effect, Layer } from "effect"
|
|
10
|
+
|
|
11
|
+
const sandboxes = Layer.unwrap(
|
|
12
|
+
Effect.map(Config.Redacted("E2B_API_KEY"), (apiKey) => E2bSandboxProvider.layer({ apiKey }))
|
|
13
|
+
).pipe(Layer.provide(BunCrypto.layer))
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`make` constructs the provider and needs Effect's `Crypto` service. `layer` delegates to it.
|
|
17
|
+
Options include `apiKey`, `apiUrl`, `domain`, `template`, `timeoutMs`, and `requestTimeoutMs`.
|
|
18
|
+
`providerOptions.e2b` can override `template` and `timeoutMs` for a create. The SDK version is
|
|
19
|
+
pinned in the root catalog. Credentials are supplied explicitly; the adapter does not read them
|
|
20
|
+
from SDK environment variables.
|
|
21
|
+
|
|
22
|
+
## Identity and lifecycle
|
|
23
|
+
|
|
24
|
+
Each logical sandbox ID is recorded in E2B metadata beside `amends-provider=e2b`. Resume queries
|
|
25
|
+
both running and paused sandboxes, including every page, so a fresh host can find the same machine.
|
|
26
|
+
Unknown IDs fail without allocation. A duplicate logical ID fails without modifying the existing
|
|
27
|
+
machine. Sandboxes outlive the provider; `createScoped` destroys its sandbox on scope exit.
|
|
28
|
+
|
|
29
|
+
**E2B does not provide atomic reservation of a custom sandbox name.** Creates are serialized within
|
|
30
|
+
one provider and check metadata before and after allocation. A detected concurrent create deletes
|
|
31
|
+
only its own allocation. Two hosts can still race while each sees no other allocation. If duplicates
|
|
32
|
+
exist, resume fails with `UnknownError` instead of selecting a machine arbitrarily. Applications
|
|
33
|
+
that create the same explicit ID on different hosts must serialize those creates externally. IDs
|
|
34
|
+
generated by the adapter are UUIDs. E2B volumes are not used for naming because they require access
|
|
35
|
+
to a separate private beta.
|
|
36
|
+
|
|
37
|
+
`stop` uses `pause({ mode: "filesystem" })`, which preserves files and ends processes. Resume
|
|
38
|
+
cold-boots the machine. Repeated stop and destroy succeed. E2B requires a maximum running lifetime:
|
|
39
|
+
the default here is one hour, after which E2B pauses with filesystem-only persistence. Set
|
|
40
|
+
`timeoutMs` within the account's permitted limit. The host must resume the sandbox and restart its
|
|
41
|
+
services after that pause; the adapter does not renew timeouts in the background. Auto-resume on
|
|
42
|
+
port traffic is disabled because it cannot restart services after a filesystem-only pause.
|
|
43
|
+
|
|
44
|
+
A contract template prepares each new machine, then its network policy applies. Preparation failure
|
|
45
|
+
or interruption destroys that allocation before returning. Template snapshots are not cached;
|
|
46
|
+
`template` can select an E2B template or previously prepared snapshot supplied by the operator.
|
|
47
|
+
|
|
48
|
+
## Files, processes, and ports
|
|
49
|
+
|
|
50
|
+
The image must provide Linux `/proc`, POSIX shells, Python 3 for the conformance server, and GNU
|
|
51
|
+
core utilities including `setsid`, `stat`, `find`, `base64`, and `mktemp`. E2B's base image supplies
|
|
52
|
+
the tools used by the adapter. File reads and writes transfer whole files. File handles, watch,
|
|
53
|
+
glob, and append flags are unsupported and fail with `PlatformError`. Exclusive-write checks and
|
|
54
|
+
mode application use multiple API calls and are not atomic against other writers.
|
|
55
|
+
|
|
56
|
+
Each command runs in a process group with stdout and stderr written to private files. Polling
|
|
57
|
+
reads them as bytes, preserving non-UTF-8 data and final output without a newline. stdin uses E2B's
|
|
58
|
+
byte API and closes when its sink ends. Environment scripts avoid placing environment values in
|
|
59
|
+
recorded command lines. Commands support cwd, environment replacement or extension, pipelines,
|
|
60
|
+
shell mode, ignored streams, and sinks. Extra file descriptors and host-inherited streams fail.
|
|
61
|
+
|
|
62
|
+
Scope exit kills a referenced command's process group and removes its scratch directory.
|
|
63
|
+
`unref` leaves the process running after its scope closes. `kill` uses SIGKILL regardless of the
|
|
64
|
+
requested signal. Handles capture the Linux boot ID and refuse to signal an old PID after resume.
|
|
65
|
+
Unreferenced commands keep their output files until removed by sandbox code or sandbox destruction.
|
|
66
|
+
Output polling costs API requests and holds at most one MiB per read, while output files can grow
|
|
67
|
+
until their command's scope closes. Output is unavailable while the sandbox is paused.
|
|
68
|
+
|
|
69
|
+
Port markers in `/var/tmp/amends/ports` survive pause and make ports exposed through one handle
|
|
70
|
+
visible to another. Independent markers avoid lost updates when hosts expose different ports.
|
|
71
|
+
Endpoints use HTTPS or WSS and E2B's `e2b-traffic-access-token` header; other headers, including
|
|
72
|
+
`Authorization`, remain available to the application. E2B's private traffic mode applies to the
|
|
73
|
+
machine, while port markers describe which endpoints this adapter returns; they are not per-port
|
|
74
|
+
firewall rules.
|
|
75
|
+
|
|
76
|
+
## Network policies
|
|
77
|
+
|
|
78
|
+
Allow-all, deny-all, and allow lists of hosts and CIDRs without denied exceptions are supported.
|
|
79
|
+
An allow list with `deniedCidrs` fails with `UnsupportedError` before allocation: E2B's allow rules
|
|
80
|
+
override deny rules, while the contract requires the opposite. An empty allow list blocks egress.
|
|
81
|
+
Host filtering follows E2B's HTTP Host/TLS SNI filtering on ports 80/443 and its DNS exception;
|
|
82
|
+
other protocols require IP/CIDR allowances. See [E2B's network documentation](https://docs.e2b.dev/network/internet-access).
|
|
83
|
+
|
|
84
|
+
Request transformations fail with `UnsupportedError`. E2B's per-host transforms lack the contract's
|
|
85
|
+
path-prefix and matching-header conditions; the adapter never broadens credential injection.
|
|
86
|
+
|
|
87
|
+
## Verification
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
bun run --cwd adapters/sandbox-e2b typecheck
|
|
91
|
+
bun run test -- adapters/sandbox-e2b/test/provider.test.ts
|
|
92
|
+
AMENDS_TEST_E2B=1 E2B_API_KEY=... bun run test -- adapters/sandbox-e2b/test
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The default tests exercise the real SDK against a local fake control plane, including error mapping,
|
|
96
|
+
network preflight, duplicate detection, cleanup ownership, pagination, and lifecycle payloads.
|
|
97
|
+
Live tests run the shared conformance suites and E2B-specific reboot, binary stdin/EOF, and network
|
|
98
|
+
regressions. They allocate paid cloud machines and are skipped unless both variables are set.
|
|
99
|
+
Live verification requires an E2B region that supports filesystem-only persistence; a rejected
|
|
100
|
+
pause remains an error and is never silently substituted with memory persistence.
|
package/index.d.ts
ADDED
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA"}
|
package/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandboxes on E2B for the `@amends-dev/sandbox` contract.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.1.0
|
|
5
|
+
*/
|
|
6
|
+
// @barrel: Auto-generated exports. Do not edit manually.
|
|
7
|
+
/**
|
|
8
|
+
* @since 0.1.0
|
|
9
|
+
*/
|
|
10
|
+
export * as E2bSandboxProvider from "./E2bSandboxProvider.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,yDAAyD;AAEzD;;GAEG;AACH,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Maps E2B SDK failures to the sandbox and Effect platform contracts. */
|
|
2
|
+
import { SandboxError } from "@amends-dev/sandbox";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as PlatformError from "effect/PlatformError";
|
|
5
|
+
export declare const providerId = "e2b";
|
|
6
|
+
export declare const sandboxError: (reason: SandboxError.SandboxErrorReason, cause?: unknown) => SandboxError.SandboxError;
|
|
7
|
+
export declare const call: <A>(request: () => Promise<A>) => Effect.Effect<A, SandboxError.SandboxError, never>;
|
|
8
|
+
export declare const fromE2bError: (error: unknown) => SandboxError.SandboxError;
|
|
9
|
+
export type PlatformModule = "FileSystem" | "ChildProcess";
|
|
10
|
+
export declare const callPlatform: <A>(module: PlatformModule, method: string, request: () => Promise<A>, path?: string) => Effect.Effect<A, PlatformError.PlatformError, never>;
|
|
11
|
+
export declare const toPlatformError: (module: PlatformModule, method: string, error: unknown, path?: string) => PlatformError.PlatformError;
|
|
12
|
+
export declare const systemErrorTagOf: (error: unknown) => PlatformError.SystemErrorTag;
|
|
13
|
+
//# sourceMappingURL=call.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../src/internal/call.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAE1E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AASlD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAA;AAErD,eAAO,MAAM,UAAU,QAAQ,CAAA;AAE/B,eAAO,MAAM,YAAY,WAAY,YAAY,CAAC,kBAAkB,UAAU,OAAO,8BACb,CAAA;AAExE,eAAO,MAAM,IAAI,GAAI,CAAC,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,uDAA6D,CAAA;AAE9G,eAAO,MAAM,YAAY,UAAW,OAAO,8BAAyC,CAAA;AA0BpF,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,cAAc,CAAA;AAE1D,eAAO,MAAM,YAAY,GAAI,CAAC,UAAU,cAAc,UAAU,MAAM,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,SAAS,MAAM,yDACX,CAAA;AAErG,eAAO,MAAM,eAAe,WAAY,cAAc,UAAU,MAAM,SAAS,OAAO,SAAS,MAAM,gCAQjG,CAAA;AAEJ,eAAO,MAAM,gBAAgB,UAAW,OAAO,KAAG,aAAa,CAAC,cAe/D,CAAA"}
|
package/internal/call.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** Maps E2B SDK failures to the sandbox and Effect platform contracts. */
|
|
2
|
+
import { SandboxError } from "@amends-dev/sandbox";
|
|
3
|
+
import { AuthenticationError, InvalidArgumentError, NotFoundError, SandboxError as E2bError, ServiceBusyError, TimeoutError } from "e2b";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import * as PlatformError from "effect/PlatformError";
|
|
6
|
+
export const providerId = "e2b";
|
|
7
|
+
export const sandboxError = (reason, cause) => new SandboxError.SandboxError({ provider: providerId, reason, cause });
|
|
8
|
+
export const call = (request) => Effect.tryPromise({ try: request, catch: fromE2bError });
|
|
9
|
+
export const fromE2bError = (error) => sandboxError(reasonOf(error), error);
|
|
10
|
+
const reasonOf = (error) => {
|
|
11
|
+
const description = error instanceof Error ? error.message : String(error);
|
|
12
|
+
if (error instanceof NotFoundError)
|
|
13
|
+
return new SandboxError.NotFoundError({ description });
|
|
14
|
+
if (error instanceof AuthenticationError)
|
|
15
|
+
return new SandboxError.AuthenticationError({ description });
|
|
16
|
+
if (error instanceof InvalidArgumentError)
|
|
17
|
+
return new SandboxError.InvalidOptionsError({ description });
|
|
18
|
+
if (error instanceof E2bError) {
|
|
19
|
+
if (error.statusCode === 401 || error.statusCode === 403)
|
|
20
|
+
return new SandboxError.AuthenticationError({ description });
|
|
21
|
+
if (error.statusCode === 404)
|
|
22
|
+
return new SandboxError.NotFoundError({ description });
|
|
23
|
+
if (error.statusCode === 400 || error.statusCode === 422)
|
|
24
|
+
return new SandboxError.InvalidOptionsError({ description });
|
|
25
|
+
// E2B owns machine IDs; a conflict is a lifecycle transition, not our metadata name check.
|
|
26
|
+
if (error.statusCode === 409)
|
|
27
|
+
return new SandboxError.UnavailableError({ description });
|
|
28
|
+
}
|
|
29
|
+
if (error instanceof TimeoutError ||
|
|
30
|
+
error instanceof ServiceBusyError ||
|
|
31
|
+
(error instanceof E2bError && (error.statusCode === 429 || (error.statusCode ?? 0) >= 500))) {
|
|
32
|
+
return new SandboxError.UnavailableError({ description });
|
|
33
|
+
}
|
|
34
|
+
return new SandboxError.UnknownError({ description });
|
|
35
|
+
};
|
|
36
|
+
export const callPlatform = (module, method, request, path) => Effect.tryPromise({ try: request, catch: (error) => toPlatformError(module, method, error, path) });
|
|
37
|
+
export const toPlatformError = (module, method, error, path) => PlatformError.systemError({
|
|
38
|
+
_tag: systemErrorTagOf(error),
|
|
39
|
+
module,
|
|
40
|
+
method,
|
|
41
|
+
pathOrDescriptor: path,
|
|
42
|
+
description: error instanceof Error ? error.message : String(error),
|
|
43
|
+
cause: error
|
|
44
|
+
});
|
|
45
|
+
export const systemErrorTagOf = (error) => {
|
|
46
|
+
if (error instanceof NotFoundError || (error instanceof E2bError && error.statusCode === 404))
|
|
47
|
+
return "NotFound";
|
|
48
|
+
if (error instanceof AuthenticationError ||
|
|
49
|
+
(error instanceof E2bError && (error.statusCode === 401 || error.statusCode === 403)))
|
|
50
|
+
return "PermissionDenied";
|
|
51
|
+
if (error instanceof TimeoutError)
|
|
52
|
+
return "TimedOut";
|
|
53
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
54
|
+
if (/no such file or directory|file not found/i.test(message))
|
|
55
|
+
return "NotFound";
|
|
56
|
+
if (/file exists|already exists/i.test(message))
|
|
57
|
+
return "AlreadyExists";
|
|
58
|
+
if (/permission denied|operation not permitted/i.test(message))
|
|
59
|
+
return "PermissionDenied";
|
|
60
|
+
if (/not a directory|is a directory|too many levels of symbolic links/i.test(message))
|
|
61
|
+
return "BadResource";
|
|
62
|
+
if (/resource busy/i.test(message))
|
|
63
|
+
return "Busy";
|
|
64
|
+
return "Unknown";
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=call.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/internal/call.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An E2B sandbox's files, read and written whole through E2B's file API, so that a read
|
|
3
|
+
* holds the whole file in memory, whatever its size, and otherwise worked on with the sandbox's
|
|
4
|
+
* POSIX tools, one command each, which E2B runs and answers at once. Paths are the sandbox's;
|
|
5
|
+
* a relative one is resolved against the working directory. A failure is the error the tool's
|
|
6
|
+
* message names, as Effect's own file systems name an `errno`.
|
|
7
|
+
*/
|
|
8
|
+
import { type Sandbox as E2BSandbox } from "e2b";
|
|
9
|
+
import * as FileSystem from "effect/FileSystem";
|
|
10
|
+
/** The file system of `sandbox`, whose relative paths start in `workingDirectory`. */
|
|
11
|
+
export declare const makeFileSystem: (sandbox: E2BSandbox, workingDirectory: string) => FileSystem.FileSystem;
|
|
12
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/internal/files.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAoB,KAAK,OAAO,IAAI,UAAU,EAAE,MAAM,KAAK,CAAA;AAGlE,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAgB/C,sFAAsF;AACtF,eAAO,MAAM,cAAc,YAAa,UAAU,oBAAoB,MAAM,KAAG,UAAU,CAAC,UA2LzF,CAAA"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An E2B sandbox's files, read and written whole through E2B's file API, so that a read
|
|
3
|
+
* holds the whole file in memory, whatever its size, and otherwise worked on with the sandbox's
|
|
4
|
+
* POSIX tools, one command each, which E2B runs and answers at once. Paths are the sandbox's;
|
|
5
|
+
* a relative one is resolved against the working directory. A failure is the error the tool's
|
|
6
|
+
* message names, as Effect's own file systems name an `errno`.
|
|
7
|
+
*/
|
|
8
|
+
import { CommandExitError } from "e2b";
|
|
9
|
+
import * as ByteSize from "effect/ByteSize";
|
|
10
|
+
import * as Effect from "effect/Effect";
|
|
11
|
+
import * as FileSystem from "effect/FileSystem";
|
|
12
|
+
import * as Option from "effect/Option";
|
|
13
|
+
import * as PlatformError from "effect/PlatformError";
|
|
14
|
+
import * as Stream from "effect/Stream";
|
|
15
|
+
import { callPlatform, systemErrorTagOf, toPlatformError } from "./call.js";
|
|
16
|
+
import { quote } from "./shell.js";
|
|
17
|
+
/** Defines `fail path message`, which fails a script with a message of the tools' own. */
|
|
18
|
+
const defineFail = `fail() { printf '%s: %s\\n' "$1" "$2" >&2; exit 1; }`;
|
|
19
|
+
/** Fails a script for a path that does not exist, as the tools would. */
|
|
20
|
+
const existing = '[ -e "$1" ] || fail "$1" "No such file or directory"';
|
|
21
|
+
/** The flag `flag`, with the space before it, when `condition` holds. */
|
|
22
|
+
const when = (condition, flag) => (condition === true ? ` ${flag}` : "");
|
|
23
|
+
/** The file system of `sandbox`, whose relative paths start in `workingDirectory`. */
|
|
24
|
+
export const makeFileSystem = (sandbox, workingDirectory) => {
|
|
25
|
+
const resolve = (path) => (path.startsWith("/") ? path : `${workingDirectory}/${path}`);
|
|
26
|
+
/**
|
|
27
|
+
* Runs `script` in sh with `args` as its positional parameters, the first being the path it works
|
|
28
|
+
* on, and returns what it prints. `fail path message` fails it with a message of the tools' own.
|
|
29
|
+
*/
|
|
30
|
+
const run = (method, script, args) => Effect.tryPromise({
|
|
31
|
+
try: () => sandbox.commands
|
|
32
|
+
.run(`sh -c ${quote(`${defineFail}; ${script}`)} sh ${args.map(quote).join(" ")}`, { envs: { LC_ALL: "C" } })
|
|
33
|
+
.catch((error) => {
|
|
34
|
+
if (error instanceof CommandExitError)
|
|
35
|
+
return error;
|
|
36
|
+
throw error;
|
|
37
|
+
}),
|
|
38
|
+
catch: (error) => toPlatformError("FileSystem", method, error, args[0])
|
|
39
|
+
}).pipe(Effect.flatMap(({ exitCode, stdout, stderr }) => exitCode === 0
|
|
40
|
+
? Effect.succeed(stdout)
|
|
41
|
+
: Effect.fail(PlatformError.systemError({
|
|
42
|
+
_tag: systemErrorTagOf(stderr),
|
|
43
|
+
module: "FileSystem",
|
|
44
|
+
method,
|
|
45
|
+
pathOrDescriptor: args[0],
|
|
46
|
+
description: stderr.trim()
|
|
47
|
+
}))));
|
|
48
|
+
const makeTempDirectory = (options) => Effect.map(run("makeTempDirectory", 'mktemp -d -- "${1:-${TMPDIR:-/tmp}}/${2}XXXXXX"', [
|
|
49
|
+
options?.directory === undefined ? "" : resolve(options.directory),
|
|
50
|
+
options?.prefix ?? ""
|
|
51
|
+
]), withoutNewline);
|
|
52
|
+
// A temporary file is made in a temporary directory of its own, as Effect's own file systems do.
|
|
53
|
+
const makeTempFile = (options) => Effect.map(run("makeTempFile", [
|
|
54
|
+
'directory=$(mktemp -d -- "${1:-${TMPDIR:-/tmp}}/${2}XXXXXX")',
|
|
55
|
+
'mktemp --suffix="$3" -- "$directory/XXXXXXXXXXXX"'
|
|
56
|
+
].join(" && "), [
|
|
57
|
+
options?.directory === undefined ? "" : resolve(options.directory),
|
|
58
|
+
options?.prefix ?? "",
|
|
59
|
+
options?.suffix ?? ""
|
|
60
|
+
]), withoutNewline);
|
|
61
|
+
const remove = (path, options) => Effect.asVoid(run("remove", `rm${when(options?.recursive, "-r")}${when(options?.force, "-f")} -- "$1"`, [resolve(path)]));
|
|
62
|
+
return FileSystem.make({
|
|
63
|
+
access: (path, options) => Effect.asVoid(run("access", [
|
|
64
|
+
existing,
|
|
65
|
+
...(options?.readable === true ? ['[ -r "$1" ] || fail "$1" "Permission denied"'] : []),
|
|
66
|
+
...(options?.writable === true ? ['[ -w "$1" ] || fail "$1" "Permission denied"'] : [])
|
|
67
|
+
].join("; "), [resolve(path)])),
|
|
68
|
+
// `-n` leaves existing files as they are, as Node's `cp` does without `force`.
|
|
69
|
+
copy: (fromPath, toPath, options) => Effect.asVoid(run("copy", `cp -RT${when(options?.overwrite !== true, "-n")}` +
|
|
70
|
+
`${when(options?.preserveTimestamps, "--preserve=timestamps")} -- "$1" "$2"`, [resolve(fromPath), resolve(toPath)])),
|
|
71
|
+
copyFile: (fromPath, toPath) => Effect.asVoid(run("copyFile", 'cp -T -- "$1" "$2"', [resolve(fromPath), resolve(toPath)])),
|
|
72
|
+
chmod: (path, mode) => Effect.asVoid(run("chmod", `chmod ${mode.toString(8)} -- "$1"`, [resolve(path)])),
|
|
73
|
+
chown: (path, uid, gid) => Effect.asVoid(run("chown", `chown ${uid}:${gid} -- "$1"`, [resolve(path)])),
|
|
74
|
+
glob: () => Effect.fail(unsupported("glob", "An E2B sandbox's files cannot be globbed")),
|
|
75
|
+
link: (fromPath, toPath) => Effect.asVoid(run("link", 'ln -- "$1" "$2"', [resolve(fromPath), resolve(toPath)])),
|
|
76
|
+
makeDirectory: (path, options) => {
|
|
77
|
+
const mode = options?.mode === undefined ? "" : ` -m ${options.mode.toString(8)}`;
|
|
78
|
+
return Effect.asVoid(run("makeDirectory", `mkdir${when(options?.recursive, "-p")}${mode} -- "$1"`, [resolve(path)]));
|
|
79
|
+
},
|
|
80
|
+
makeTempDirectory,
|
|
81
|
+
makeTempDirectoryScoped: (options) => Effect.acquireRelease(makeTempDirectory(options), (directory) => Effect.orDie(remove(directory, { recursive: true }))),
|
|
82
|
+
makeTempFile,
|
|
83
|
+
makeTempFileScoped: (options) => Effect.acquireRelease(makeTempFile(options), (file) => Effect.orDie(remove(file.slice(0, file.lastIndexOf("/")), { recursive: true }))),
|
|
84
|
+
open: () => Effect.fail(unsupported("open", "An E2B sandbox's files are read and written whole")),
|
|
85
|
+
readDirectory: (path, options) => Effect.map(run("readDirectory", [
|
|
86
|
+
existing,
|
|
87
|
+
'[ -d "$1" ] || fail "$1" "Not a directory"',
|
|
88
|
+
`cd -- "$1" && find . -mindepth 1${when(options?.recursive !== true, "-maxdepth 1")} -printf '%P\\0'`
|
|
89
|
+
].join("; "), [resolve(path)]),
|
|
90
|
+
// Names end in NUL, which no name holds.
|
|
91
|
+
(names) => names.split("\0").slice(0, -1)),
|
|
92
|
+
readFile: (path) => Effect.map(callPlatform("FileSystem", "readFile", () => sandbox.files.read(resolve(path), { format: "bytes" }), resolve(path)), (buffer) => new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)),
|
|
93
|
+
readLink: (path) => run("readLink", 'readlink -vn -- "$1"', [resolve(path)]),
|
|
94
|
+
realPath: (path) => Effect.map(run("realPath", 'realpath -e -- "$1"', [resolve(path)]), withoutNewline),
|
|
95
|
+
remove,
|
|
96
|
+
rename: (oldPath, newPath) => Effect.asVoid(run("rename", 'mv -T -- "$1" "$2"', [resolve(oldPath), resolve(newPath)])),
|
|
97
|
+
stat: (path) => Effect.map(run("stat", `stat -L -c '%f %s %.9Y %.9X %.9W %d %i %h %u %g %r %o %b' -- "$1"`, [resolve(path)]), fileInfoOf),
|
|
98
|
+
// A link's target is kept as given; a relative one is relative to the link's directory.
|
|
99
|
+
symlink: (target, path) => Effect.asVoid(run("symlink", 'ln -s -- "$1" "$2"', [target, resolve(path)])),
|
|
100
|
+
truncate: (path, length) => Effect.asVoid(run("truncate", [existing, `truncate -s ${length ?? 0} -- "$1"`].join("; "), [resolve(path)])),
|
|
101
|
+
utimes: (path, atime, mtime) => Effect.asVoid(run("utimes", [existing, 'touch -c -a -d "@$2" -- "$1" && touch -c -m -d "@$3" -- "$1"'].join("; "), [
|
|
102
|
+
resolve(path),
|
|
103
|
+
secondsOf(atime),
|
|
104
|
+
secondsOf(mtime)
|
|
105
|
+
])),
|
|
106
|
+
watch: () => Stream.fail(unsupported("watch", "An E2B sandbox's files cannot be watched")),
|
|
107
|
+
writeFile: Effect.fnUntraced(function* (path, data, options) {
|
|
108
|
+
const flag = options?.flag ?? "w";
|
|
109
|
+
if (flag !== "w" && flag !== "w+" && flag !== "wx" && flag !== "wx+") {
|
|
110
|
+
return yield* unsupported("writeFile", `An E2B sandbox's files are not opened with ${flag}`);
|
|
111
|
+
}
|
|
112
|
+
const resolved = resolve(path);
|
|
113
|
+
// E2B makes a file's missing directories, and writes over a file it is asked not to,
|
|
114
|
+
// so the directory and the file are checked first, as opening the file would.
|
|
115
|
+
const created = yield* run("writeFile", [
|
|
116
|
+
'[ -d "$(dirname -- "$1")" ] || fail "$1" "No such file or directory"',
|
|
117
|
+
...(flag.startsWith("wx") ? ['[ ! -e "$1" ] || fail "$1" "File exists"'] : []),
|
|
118
|
+
'[ -e "$1" ] || printf created'
|
|
119
|
+
].join("; "), [resolved]);
|
|
120
|
+
yield* callPlatform("FileSystem", "writeFile", () => sandbox.files.write(resolved, new Uint8Array(data).buffer), resolved);
|
|
121
|
+
// A mode applies to the file the write creates, as when a file is opened.
|
|
122
|
+
if (options?.mode !== undefined && created === "created") {
|
|
123
|
+
yield* run("writeFile", `chmod ${options.mode.toString(8)} -- "$1"`, [resolved]);
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
/** The file information `stat` prints in the format the file system asks it for. */
|
|
129
|
+
const fileInfoOf = (printed) => {
|
|
130
|
+
const [mode, size, mtime, atime, birthtime, dev, ino, nlink, uid, gid, rdev, blksize, blocks] = withoutNewline(printed).split(" ");
|
|
131
|
+
const modeBits = Number.parseInt(mode ?? "0", 16);
|
|
132
|
+
return {
|
|
133
|
+
type: fileTypeOf(modeBits),
|
|
134
|
+
mtime: dateOf(mtime),
|
|
135
|
+
atime: dateOf(atime),
|
|
136
|
+
birthtime: dateOf(birthtime),
|
|
137
|
+
dev: Number(dev),
|
|
138
|
+
ino: Option.some(Number(ino)),
|
|
139
|
+
mode: modeBits,
|
|
140
|
+
nlink: Option.some(Number(nlink)),
|
|
141
|
+
uid: Option.some(Number(uid)),
|
|
142
|
+
gid: Option.some(Number(gid)),
|
|
143
|
+
rdev: Option.some(Number(rdev)),
|
|
144
|
+
size: ByteSize.bytes(BigInt(size ?? "0")),
|
|
145
|
+
blksize: Option.some(ByteSize.bytes(BigInt(blksize ?? "0"))),
|
|
146
|
+
blocks: Option.some(Number(blocks))
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
/** The type a file's mode names in its format bits. */
|
|
150
|
+
const fileTypeOf = (mode) => {
|
|
151
|
+
switch (mode & 0o170000) {
|
|
152
|
+
case 0o100000:
|
|
153
|
+
return "File";
|
|
154
|
+
case 0o040000:
|
|
155
|
+
return "Directory";
|
|
156
|
+
case 0o120000:
|
|
157
|
+
return "SymbolicLink";
|
|
158
|
+
case 0o060000:
|
|
159
|
+
return "BlockDevice";
|
|
160
|
+
case 0o020000:
|
|
161
|
+
return "CharacterDevice";
|
|
162
|
+
case 0o010000:
|
|
163
|
+
return "FIFO";
|
|
164
|
+
case 0o140000:
|
|
165
|
+
return "Socket";
|
|
166
|
+
default:
|
|
167
|
+
return "Unknown";
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
/** A time `stat` prints in seconds, which it prints as 0 or `-` when the file system keeps none. */
|
|
171
|
+
const dateOf = (seconds) => {
|
|
172
|
+
const value = Number(seconds);
|
|
173
|
+
return Number.isFinite(value) && value > 0 ? Option.some(new Date(value * 1000)) : Option.none();
|
|
174
|
+
};
|
|
175
|
+
const secondsOf = (time) => String(typeof time === "number" ? time : time.getTime() / 1000);
|
|
176
|
+
const withoutNewline = (printed) => (printed.endsWith("\n") ? printed.slice(0, -1) : printed);
|
|
177
|
+
const unsupported = (method, description) => PlatformError.badArgument({ module: "FileSystem", method, description });
|
|
178
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/internal/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** E2B allows destinations before evaluating deny rules; denied exceptions cannot be represented. */
|
|
2
|
+
import { SandboxError } from "@amends-dev/sandbox";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
export declare const networkSettingsOf: (value: {
|
|
5
|
+
readonly _tag: "AllowAll";
|
|
6
|
+
} | {
|
|
7
|
+
readonly _tag: "DenyAll";
|
|
8
|
+
} | {
|
|
9
|
+
readonly _tag: "AllowList";
|
|
10
|
+
readonly allowedHosts: readonly string[];
|
|
11
|
+
readonly allowedCidrs: readonly string[];
|
|
12
|
+
readonly deniedCidrs: readonly string[];
|
|
13
|
+
}) => Effect.Effect<never, SandboxError.SandboxError, never> | Effect.Effect<{
|
|
14
|
+
allowOut: string[];
|
|
15
|
+
denyOut: string[];
|
|
16
|
+
}, never, never>;
|
|
17
|
+
//# sourceMappingURL=network.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/internal/network.ts"],"names":[],"mappings":"AAAA,qGAAqG;AAErG,OAAO,EAAW,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;gBAW5B,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** E2B allows destinations before evaluating deny rules; denied exceptions cannot be represented. */
|
|
2
|
+
import { Network, SandboxError } from "@amends-dev/sandbox";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import { sandboxError } from "./call.js";
|
|
5
|
+
export const networkSettingsOf = Network.NetworkPolicy.match({
|
|
6
|
+
AllowAll: () => Effect.succeed({ allowOut: [], denyOut: [] }),
|
|
7
|
+
DenyAll: () => Effect.succeed({ allowOut: [], denyOut: ["0.0.0.0/0"] }),
|
|
8
|
+
AllowList: ({ allowedHosts, allowedCidrs, deniedCidrs }) => deniedCidrs.length > 0
|
|
9
|
+
? Effect.fail(sandboxError(new SandboxError.UnsupportedError({ description: "E2B's allow rules override denied CIDR exceptions" })))
|
|
10
|
+
: Effect.succeed({ allowOut: [...allowedHosts, ...allowedCidrs], denyOut: ["0.0.0.0/0"] })
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=network.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/internal/network.ts"],"names":[],"mappings":"AAAA,qGAAqG;AAErG,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC;IAC3D,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC7D,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;IACvE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE,CACzD,WAAW,CAAC,MAAM,GAAG,CAAC;QACpB,CAAC,CAAC,MAAM,CAAC,IAAI,CACT,YAAY,CACV,IAAI,YAAY,CAAC,gBAAgB,CAAC,EAAE,WAAW,EAAE,mDAAmD,EAAE,CAAC,CACxG,CACF;QACH,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,YAAY,EAAE,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;CAC/F,CAAC,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2B commands run in their own process groups. Output is read from files byte for byte because
|
|
3
|
+
* the SDK decodes stdout and stderr as UTF-8. Closing a referenced process scope kills its group;
|
|
4
|
+
* an unreferenced process remains until the sandbox stops. Polling reads output without retaining
|
|
5
|
+
* an unbounded SDK event stream or buffering all output on the host.
|
|
6
|
+
*/
|
|
7
|
+
import { type Sandbox as E2bSandbox } from "e2b";
|
|
8
|
+
import * as Crypto from "effect/Crypto";
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import * as PlatformError from "effect/PlatformError";
|
|
11
|
+
import * as ChildProcess from "effect/process/ChildProcess";
|
|
12
|
+
import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
|
|
13
|
+
import * as Stream from "effect/Stream";
|
|
14
|
+
export declare const makeChildProcessSpawner: (sandbox: E2bSandbox, workingDirectory: string) => Effect.Effect<{
|
|
15
|
+
spawn(command: ChildProcess.Command): Effect.Effect<ChildProcessSpawner.ChildProcessHandle, PlatformError.PlatformError, import("effect/Scope").Scope>;
|
|
16
|
+
exitCode(command: ChildProcess.Command): Effect.Effect<ChildProcessSpawner.ExitCode, PlatformError.PlatformError>;
|
|
17
|
+
streamString(command: ChildProcess.Command, options?: {
|
|
18
|
+
readonly includeStderr?: boolean | undefined;
|
|
19
|
+
}): Stream.Stream<string, PlatformError.PlatformError>;
|
|
20
|
+
streamLines(command: ChildProcess.Command, options?: {
|
|
21
|
+
readonly includeStderr?: boolean | undefined;
|
|
22
|
+
}): Stream.Stream<string, PlatformError.PlatformError>;
|
|
23
|
+
lines(command: ChildProcess.Command, options?: {
|
|
24
|
+
readonly includeStderr?: boolean | undefined;
|
|
25
|
+
}): Effect.Effect<Array<string>, PlatformError.PlatformError>;
|
|
26
|
+
string(command: ChildProcess.Command, options?: {
|
|
27
|
+
readonly includeStderr?: boolean | undefined;
|
|
28
|
+
}): Effect.Effect<string, PlatformError.PlatformError>;
|
|
29
|
+
}, never, Crypto.Crypto>;
|
|
30
|
+
//# sourceMappingURL=processes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processes.d.ts","sourceRoot":"","sources":["../../src/internal/processes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAgD,KAAK,OAAO,IAAI,UAAU,EAAE,MAAM,KAAK,CAAA;AAC9F,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,YAAY,MAAM,6BAA6B,CAAA;AAC3D,OAAO,KAAK,mBAAmB,MAAM,oCAAoC,CAAA;AAIzE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAevC,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;wBAyLlC,CAAA"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2B commands run in their own process groups. Output is read from files byte for byte because
|
|
3
|
+
* the SDK decodes stdout and stderr as UTF-8. Closing a referenced process scope kills its group;
|
|
4
|
+
* an unreferenced process remains until the sandbox stops. Polling reads output without retaining
|
|
5
|
+
* an unbounded SDK event stream or buffering all output on the host.
|
|
6
|
+
*/
|
|
7
|
+
import { SandboxNotFoundError, SandboxNotRunningError } from "e2b";
|
|
8
|
+
import * as Crypto from "effect/Crypto";
|
|
9
|
+
import * as Data from "effect/Data";
|
|
10
|
+
import * as Duration from "effect/Duration";
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import * as Option from "effect/Option";
|
|
13
|
+
import * as PlatformError from "effect/PlatformError";
|
|
14
|
+
import * as ChildProcess from "effect/process/ChildProcess";
|
|
15
|
+
import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
|
|
16
|
+
import * as Ref from "effect/Ref";
|
|
17
|
+
import * as Schedule from "effect/Schedule";
|
|
18
|
+
import * as Sink from "effect/Sink";
|
|
19
|
+
import * as Stream from "effect/Stream";
|
|
20
|
+
import { callPlatform } from "./call.js";
|
|
21
|
+
import { quote } from "./shell.js";
|
|
22
|
+
const Status = Data.taggedEnum();
|
|
23
|
+
const isRunning = Status.$is("Running");
|
|
24
|
+
const untilExit = Schedule.min([Schedule.exponential("50 millis"), Schedule.spaced("1 second")]);
|
|
25
|
+
const delayAfter = (idle) => Duration.millis(Math.min(50 * 2 ** idle, 1000));
|
|
26
|
+
const readLimit = 1024 * 1024;
|
|
27
|
+
export const makeChildProcessSpawner = Effect.fnUntraced(function* (sandbox, workingDirectory) {
|
|
28
|
+
const crypto = yield* Crypto.Crypto;
|
|
29
|
+
const spawn = Effect.fnUntraced(function* (command) {
|
|
30
|
+
const unsupported = unsupportedOption(command);
|
|
31
|
+
if (unsupported !== undefined) {
|
|
32
|
+
return yield* PlatformError.badArgument({ module: "ChildProcess", method: "spawn", description: unsupported });
|
|
33
|
+
}
|
|
34
|
+
const directory = `/tmp/amends-process-${yield* crypto.randomUUIDv4}`;
|
|
35
|
+
const referenced = yield* Ref.make(true);
|
|
36
|
+
const killed = yield* Ref.make(false);
|
|
37
|
+
const execute = (method, script) => callPlatform("ChildProcess", method, () => sandbox.commands.run(script));
|
|
38
|
+
const remove = Effect.asVoid(execute("cleanup", `rm -rf -- ${quote(directory)}`));
|
|
39
|
+
// Every scratch file is owned by this process scope, including failures before spawn returns.
|
|
40
|
+
yield* Effect.acquireRelease(execute("spawn", `mkdir -m 700 -- ${quote(directory)}`), () => Effect.flatMap(Ref.get(referenced), (value) => (value ? Effect.ignore(remove) : Effect.void)));
|
|
41
|
+
const environmentScripts = new Map(standardCommandsOf(command).flatMap((standard, index) => standard.options.env === undefined ? [] : [[standard, `${directory}/environment-${index}`]]));
|
|
42
|
+
yield* Effect.forEach(environmentScripts, ([standard, file]) => callPlatform("ChildProcess", "spawn", () => sandbox.files.write(file, environmentScriptOf(standard))), { discard: true });
|
|
43
|
+
const line = commandLine(command, workingDirectory, environmentScripts);
|
|
44
|
+
const body = [
|
|
45
|
+
`cat /proc/sys/kernel/random/boot_id > ${quote(`${directory}/boot`)}`,
|
|
46
|
+
`printf '%s' "$$" > ${quote(`${directory}/pid`)}`,
|
|
47
|
+
`{ ${line}; } >${quote(`${directory}/stdout`)} 2>${quote(`${directory}/stderr`)}`,
|
|
48
|
+
`printf '%s' "$?" >${quote(`${directory}/exit`)}`
|
|
49
|
+
].join("; ");
|
|
50
|
+
// A filesystem-only resume may reuse a PID. Old handles must never signal a new process.
|
|
51
|
+
const sameBoot = `cmp -s /proc/sys/kernel/random/boot_id ${quote(`${directory}/boot`)}`;
|
|
52
|
+
const input = stdinOf(command);
|
|
53
|
+
const killGroup = Effect.gen(function* () {
|
|
54
|
+
yield* execute("kill", `if ${sameBoot} && [ -f ${quote(`${directory}/pid`)} ]; then ` +
|
|
55
|
+
`group=$(cat ${quote(`${directory}/pid`)}); ` +
|
|
56
|
+
// A live leader must still be our unique shell. An exited leader can leave children
|
|
57
|
+
// in the group, whose group ID Linux reserves until the last member has left.
|
|
58
|
+
`if [ ! -e "/proc/$group/cmdline" ] || ` +
|
|
59
|
+
`tr '\\0' '\\n' <"/proc/$group/cmdline" | grep -Fq -- ${quote(directory)}; then ` +
|
|
60
|
+
`kill -KILL -- -"$group" 2>/dev/null || true; fi; fi`);
|
|
61
|
+
yield* Ref.set(killed, true);
|
|
62
|
+
}).pipe(Effect.catchIf((error) => error.reason.cause instanceof SandboxNotRunningError || error.reason.cause instanceof SandboxNotFoundError, () => Effect.void));
|
|
63
|
+
const process = yield* Effect.acquireRelease(callPlatform("ChildProcess", "spawn", () => sandbox.commands.run(`exec setsid -w sh -c ${quote(body)}`, {
|
|
64
|
+
background: true,
|
|
65
|
+
stdin: input !== "ignore",
|
|
66
|
+
timeoutMs: 0,
|
|
67
|
+
cwd: workingDirectory
|
|
68
|
+
})), (handle) => Effect.gen(function* () {
|
|
69
|
+
if (yield* Ref.get(referenced)) {
|
|
70
|
+
yield* Effect.ignore(killGroup);
|
|
71
|
+
// If starting failed before the group wrote its marker, terminate the SDK process.
|
|
72
|
+
yield* callPlatform("ChildProcess", "cleanup", () => sandbox.files.exists(`${directory}/pid`)).pipe(Effect.flatMap((ready) => ready ? Effect.void : callPlatform("ChildProcess", "kill", () => handle.kill())), Effect.ignore);
|
|
73
|
+
}
|
|
74
|
+
yield* Effect.ignore(callPlatform("ChildProcess", "disconnect", () => handle.disconnect()));
|
|
75
|
+
}));
|
|
76
|
+
// The group leader may be a child of setsid. Wait for its marker before callers can kill it.
|
|
77
|
+
yield* callPlatform("ChildProcess", "spawn", () => sandbox.files.exists(`${directory}/pid`)).pipe(Effect.repeat({
|
|
78
|
+
until: (ready) => ready,
|
|
79
|
+
schedule: Schedule.spaced("10 millis").pipe(Schedule.upTo({ duration: "1 second" }))
|
|
80
|
+
}), Effect.flatMap((ready) => ready
|
|
81
|
+
? Effect.void
|
|
82
|
+
: Effect.fail(PlatformError.systemError({
|
|
83
|
+
_tag: "TimedOut",
|
|
84
|
+
module: "ChildProcess",
|
|
85
|
+
method: "spawn",
|
|
86
|
+
description: "E2B process group did not start"
|
|
87
|
+
}))));
|
|
88
|
+
// Detach the SDK event reader; status and output below remain available through sandbox APIs.
|
|
89
|
+
yield* callPlatform("ChildProcess", "disconnect", () => process.disconnect());
|
|
90
|
+
const readStatus = Effect.gen(function* () {
|
|
91
|
+
if (yield* Ref.get(killed))
|
|
92
|
+
return Status.Ended();
|
|
93
|
+
const info = yield* callPlatform("ChildProcess", "status", () => sandbox.getInfo());
|
|
94
|
+
if (info.state !== "running")
|
|
95
|
+
return Status.Ended();
|
|
96
|
+
const result = yield* execute("status", `if ! ${sameBoot}; then printf ended; elif [ -f ${quote(`${directory}/exit`)} ]; then ` +
|
|
97
|
+
`cat ${quote(`${directory}/exit`)}; elif kill -0 -- -$(cat ${quote(`${directory}/pid`)}) 2>/dev/null; then ` +
|
|
98
|
+
`printf running; else printf ended; fi`);
|
|
99
|
+
if (result.stdout === "running")
|
|
100
|
+
return Status.Running();
|
|
101
|
+
if (result.stdout === "ended")
|
|
102
|
+
return Status.Ended();
|
|
103
|
+
const exitCode = Number(result.stdout);
|
|
104
|
+
return Number.isInteger(exitCode) ? Status.Exited({ exitCode }) : Status.Ended();
|
|
105
|
+
}).pipe(Effect.catchIf((error) => error.reason.cause instanceof SandboxNotFoundError || error.reason.cause instanceof SandboxNotRunningError, () => Effect.succeed(Status.Ended())));
|
|
106
|
+
const awaitExit = Effect.repeat(readStatus, { until: (status) => !isRunning(status), schedule: untilExit });
|
|
107
|
+
const readOutput = (output, offset) => Effect.map(execute("read", `tail -c +${offset + 1} -- ${quote(`${directory}/${output}`)} 2>/dev/null` +
|
|
108
|
+
` | head -c ${readLimit} | base64 -w0`), ({ stdout }) => new Uint8Array(Buffer.from(stdout, "base64")));
|
|
109
|
+
const outputOf = (output) => Stream.paginate({ offset: 0, idle: 0, ended: false }, Effect.fnUntraced(function* ({ offset, idle, ended }) {
|
|
110
|
+
const bytes = yield* readOutput(output, offset);
|
|
111
|
+
if (bytes.length > 0)
|
|
112
|
+
return [[bytes], Option.some({ offset: offset + bytes.length, idle: 0, ended })];
|
|
113
|
+
if (ended)
|
|
114
|
+
return [[], Option.none()];
|
|
115
|
+
const status = yield* readStatus;
|
|
116
|
+
if (isRunning(status))
|
|
117
|
+
yield* Effect.sleep(delayAfter(idle));
|
|
118
|
+
return [[], Option.some({ offset, idle: idle + 1, ended: !isRunning(status) })];
|
|
119
|
+
}));
|
|
120
|
+
const stdin = input === "ignore"
|
|
121
|
+
? Sink.drain
|
|
122
|
+
: Sink.forEach((bytes) => callPlatform("ChildProcess", "stdin", () => sandbox.commands.sendStdin(process.pid, bytes))).pipe(Sink.mapEffect(() => callPlatform("ChildProcess", "stdin", () => sandbox.commands.closeStdin(process.pid))));
|
|
123
|
+
if (Stream.isStream(input))
|
|
124
|
+
yield* Effect.forkScoped(Stream.run(input, stdin));
|
|
125
|
+
const stdout = outputStreamOf(command, "stdout", () => outputOf("stdout"));
|
|
126
|
+
const stderr = outputStreamOf(command, "stderr", () => outputOf("stderr"));
|
|
127
|
+
return ChildProcessSpawner.makeHandle({
|
|
128
|
+
pid: ChildProcessSpawner.ProcessId(process.pid),
|
|
129
|
+
exitCode: Effect.flatMap(awaitExit, (status) => Status.$is("Exited")(status)
|
|
130
|
+
? Effect.succeed(ChildProcessSpawner.ExitCode(status.exitCode))
|
|
131
|
+
: Effect.fail(PlatformError.systemError({
|
|
132
|
+
_tag: "Unknown",
|
|
133
|
+
module: "ChildProcess",
|
|
134
|
+
method: "exitCode",
|
|
135
|
+
description: "The process was killed or ended with its sandbox"
|
|
136
|
+
}))),
|
|
137
|
+
isRunning: Effect.map(readStatus, isRunning),
|
|
138
|
+
kill: () => killGroup,
|
|
139
|
+
stdin,
|
|
140
|
+
stdout,
|
|
141
|
+
stderr,
|
|
142
|
+
all: Stream.merge(stdout, stderr),
|
|
143
|
+
getInputFd: () => Sink.drain,
|
|
144
|
+
getOutputFd: () => Stream.empty,
|
|
145
|
+
unref: Effect.as(Ref.set(referenced, false), Ref.set(referenced, true))
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
return ChildProcessSpawner.make(spawn);
|
|
149
|
+
});
|
|
150
|
+
/** Why E2B cannot run `command` as asked, or `undefined` when it can. */
|
|
151
|
+
const unsupportedOption = (command) => {
|
|
152
|
+
if (ChildProcess.isPipedCommand(command)) {
|
|
153
|
+
const { from = "stdout", to = "stdin" } = command.options;
|
|
154
|
+
if (from.startsWith("fd") || to !== "stdin") {
|
|
155
|
+
return "A E2B sandbox pipes only stdout, stderr, or both into stdin";
|
|
156
|
+
}
|
|
157
|
+
return unsupportedOption(command.left) ?? unsupportedOption(command.right);
|
|
158
|
+
}
|
|
159
|
+
const { additionalFds = {}, stdout, stderr } = command.options;
|
|
160
|
+
if (Object.keys(additionalFds).length > 0) {
|
|
161
|
+
return "A E2B sandbox gives processes no file descriptors beyond stdin, stdout, and stderr";
|
|
162
|
+
}
|
|
163
|
+
const streams = [stdinOf(command), outputOptionOf(stdout), outputOptionOf(stderr)];
|
|
164
|
+
if (streams.some((stream) => stream === "inherit" || stream === "overlapped")) {
|
|
165
|
+
return "A process in a E2B sandbox cannot share the host's standard streams";
|
|
166
|
+
}
|
|
167
|
+
return undefined;
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* The sh line that runs `command` in `workingDirectory`, or in the directory its `cwd` names,
|
|
171
|
+
* resolved against `workingDirectory`, each command of a pipe in a subshell of its own. A command
|
|
172
|
+
* given an environment runs through the script `environmentScripts` names for it.
|
|
173
|
+
*/
|
|
174
|
+
const commandLine = (command, workingDirectory, environmentScripts) => {
|
|
175
|
+
if (ChildProcess.isPipedCommand(command)) {
|
|
176
|
+
const from = command.options.from ?? "stdout";
|
|
177
|
+
const redirect = from === "stdout" ? "" : from === "all" ? " 2>&1" : " 2>&1 >/dev/null";
|
|
178
|
+
const left = commandLine(command.left, workingDirectory, environmentScripts);
|
|
179
|
+
const right = commandLine(command.right, workingDirectory, environmentScripts);
|
|
180
|
+
return `${left}${redirect} | ${right}`;
|
|
181
|
+
}
|
|
182
|
+
const { cwd, shell, stdout, stderr } = command.options;
|
|
183
|
+
const directory = cwd === undefined ? workingDirectory : cwd.startsWith("/") ? cwd : `${workingDirectory}/${cwd}`;
|
|
184
|
+
const program = shell === undefined || shell === false
|
|
185
|
+
? [command.command, ...command.args]
|
|
186
|
+
: [shell === true ? "/bin/sh" : shell, "-c", [command.command, ...command.args].join(" ")];
|
|
187
|
+
const redirects = [
|
|
188
|
+
stdinOf(command) === "ignore" ? " </dev/null" : "",
|
|
189
|
+
outputOptionOf(stdout) === "ignore" ? " >/dev/null" : "",
|
|
190
|
+
outputOptionOf(stderr) === "ignore" ? " 2>/dev/null" : ""
|
|
191
|
+
].join("");
|
|
192
|
+
const environmentScript = environmentScripts.get(command);
|
|
193
|
+
const words = [...(environmentScript === undefined ? [] : ["sh", environmentScript]), ...program].map(quote).join(" ");
|
|
194
|
+
return `(cd ${quote(directory)} && exec ${words}${redirects})`;
|
|
195
|
+
};
|
|
196
|
+
/** The commands `command` runs, in order: itself, or each command of its pipe. */
|
|
197
|
+
const standardCommandsOf = (command) => ChildProcess.isPipedCommand(command)
|
|
198
|
+
? [...standardCommandsOf(command.left), ...standardCommandsOf(command.right)]
|
|
199
|
+
: [command];
|
|
200
|
+
/**
|
|
201
|
+
* A script that deletes itself, then runs the command its arguments name with `command`'s
|
|
202
|
+
* environment: only `env`, without `extendEnv`, or the sandbox's own with `env` over it. An
|
|
203
|
+
* undefined value unsets the variable.
|
|
204
|
+
*/
|
|
205
|
+
const environmentScriptOf = (command) => {
|
|
206
|
+
const entries = Object.entries(command.options.env ?? {});
|
|
207
|
+
const set = entries.flatMap(([name, value]) => (value === undefined ? [] : [`${name}=${value}`]));
|
|
208
|
+
const unset = entries.flatMap(([name, value]) => (value === undefined ? ["-u", name] : []));
|
|
209
|
+
const words = ["env", ...(command.options.extendEnv === true ? unset : ["-i"]), ...set];
|
|
210
|
+
return `rm -f -- "$0"\nexec ${words.map(quote).join(" ")} "$@"\n`;
|
|
211
|
+
};
|
|
212
|
+
/** The input of the first command `command` runs. */
|
|
213
|
+
const stdinOf = (command) => {
|
|
214
|
+
if (ChildProcess.isPipedCommand(command))
|
|
215
|
+
return stdinOf(command.left);
|
|
216
|
+
const { stdin } = command.options;
|
|
217
|
+
if (stdin === undefined)
|
|
218
|
+
return "pipe";
|
|
219
|
+
return typeof stdin === "string" || Stream.isStream(stdin) ? stdin : stdin.stream;
|
|
220
|
+
};
|
|
221
|
+
const outputOptionOf = (option) => {
|
|
222
|
+
if (option === undefined)
|
|
223
|
+
return "pipe";
|
|
224
|
+
return typeof option === "string" || Sink.isSink(option) ? option : (option.stream ?? "pipe");
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* The handle's stream of what the last command `command` runs writes to `output`: nothing when it
|
|
228
|
+
* is ignored, and passed through the sink the command gives for it.
|
|
229
|
+
*/
|
|
230
|
+
const outputStreamOf = (command, output, stream) => {
|
|
231
|
+
if (ChildProcess.isPipedCommand(command))
|
|
232
|
+
return outputStreamOf(command.right, output, stream);
|
|
233
|
+
const option = outputOptionOf(command.options[output]);
|
|
234
|
+
if (option === "ignore")
|
|
235
|
+
return Stream.empty;
|
|
236
|
+
return Sink.isSink(option) ? Stream.transduce(stream(), option) : stream();
|
|
237
|
+
};
|
|
238
|
+
//# sourceMappingURL=processes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processes.js","sourceRoot":"","sources":["../../src/internal/processes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/internal/shell.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,KAAK,SAAU,MAAM,WAAyC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/internal/shell.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amends-dev/sandbox-e2b",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Sandboxes on E2B for the @amends-dev/sandbox contract.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://github.com/amends-dev/amends/tree/main/adapters/sandbox-e2b#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/amends-dev/amends.git",
|
|
10
|
+
"directory": "adapters/sandbox-e2b"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/amends-dev/amends/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"agent",
|
|
17
|
+
"e2b",
|
|
18
|
+
"effect",
|
|
19
|
+
"sandbox"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"exports": {
|
|
24
|
+
".": "./index.js",
|
|
25
|
+
"./*": "./*.js",
|
|
26
|
+
"./internal/*": null
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@amends-dev/sandbox": "^0.1.0",
|
|
30
|
+
"e2b": "^2.56.0"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"effect": "^4.0.0"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
}
|
|
38
|
+
}
|