isol8 0.5.1 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,315 +1,176 @@
1
- // src/client/remote.ts
2
- class RemoteIsol8 {
3
- host;
4
- apiKey;
5
- sessionId;
6
- isol8Options;
7
- constructor(options, isol8Options) {
8
- this.host = options.host.replace(/\/$/, "");
9
- this.apiKey = options.apiKey;
10
- this.sessionId = options.sessionId;
11
- this.isol8Options = isol8Options;
12
- }
13
- async start() {
14
- const res = await this.fetch("/health");
15
- if (!res.ok) {
16
- throw new Error(`Remote server health check failed: ${res.status}`);
17
- }
18
- }
19
- async stop() {
20
- if (this.sessionId) {
21
- await this.fetch(`/session/${this.sessionId}`, { method: "DELETE" });
22
- }
23
- }
24
- async execute(req) {
25
- const res = await this.fetch("/execute", {
26
- method: "POST",
27
- body: JSON.stringify({
28
- request: req,
29
- options: this.isol8Options,
30
- sessionId: this.sessionId
31
- })
32
- });
33
- if (!res.ok) {
34
- const body = await res.json().catch(() => ({}));
35
- throw new Error(`Execution failed: ${body.error ?? res.statusText}`);
36
- }
37
- return res.json();
38
- }
39
- async* executeStream(req) {
40
- const res = await this.fetch("/execute/stream", {
41
- method: "POST",
42
- body: JSON.stringify({
43
- request: req,
44
- options: this.isol8Options,
45
- sessionId: this.sessionId
46
- })
47
- });
48
- if (!res.ok) {
49
- const body = await res.json().catch(() => ({}));
50
- throw new Error(`Stream failed: ${body.error ?? res.statusText}`);
51
- }
52
- if (!res.body) {
53
- throw new Error("No response body for streaming");
54
- }
55
- const reader = res.body.getReader();
56
- const decoder = new TextDecoder;
57
- let buffer = "";
58
- try {
59
- while (true) {
60
- const { done, value } = await reader.read();
61
- if (done) {
62
- break;
63
- }
64
- buffer += decoder.decode(value, { stream: true });
65
- const lines = buffer.split(`
66
- `);
67
- buffer = lines.pop() ?? "";
68
- for (const line of lines) {
69
- if (line.startsWith("data: ")) {
70
- const json = line.slice(6).trim();
71
- if (json) {
72
- yield JSON.parse(json);
73
- }
74
- }
75
- }
76
- }
77
- if (buffer.startsWith("data: ")) {
78
- const json = buffer.slice(6).trim();
79
- if (json) {
80
- yield JSON.parse(json);
81
- }
82
- }
83
- } finally {
84
- reader.releaseLock();
85
- }
86
- }
87
- async putFile(path, content) {
88
- if (!this.sessionId) {
89
- throw new Error("File operations require a sessionId (persistent mode)");
90
- }
91
- const base64 = typeof content === "string" ? Buffer.from(content).toString("base64") : content.toString("base64");
92
- const res = await this.fetch("/file", {
93
- method: "POST",
94
- body: JSON.stringify({
95
- sessionId: this.sessionId,
96
- path,
97
- content: base64
98
- })
99
- });
100
- if (!res.ok) {
101
- throw new Error(`File upload failed: ${res.statusText}`);
102
- }
103
- }
104
- async getFile(path) {
105
- if (!this.sessionId) {
106
- throw new Error("File operations require a sessionId (persistent mode)");
107
- }
108
- const params = new URLSearchParams({ sessionId: this.sessionId, path });
109
- const res = await this.fetch(`/file?${params}`);
110
- if (!res.ok) {
111
- throw new Error(`File download failed: ${res.statusText}`);
112
- }
113
- const body = await res.json();
114
- return Buffer.from(body.content, "base64");
115
- }
116
- async fetch(path, init) {
117
- return globalThis.fetch(`${this.host}${path}`, {
118
- ...init,
119
- headers: {
120
- "Content-Type": "application/json",
121
- Authorization: `Bearer ${this.apiKey}`,
122
- ...init?.headers ?? {}
123
- }
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, {
5
+ get: all[name],
6
+ enumerable: true,
7
+ configurable: true,
8
+ set: (newValue) => all[name] = () => newValue
124
9
  });
125
- }
126
- }
127
- // src/config.ts
128
- import { existsSync, readFileSync } from "node:fs";
129
- import { homedir } from "node:os";
130
- import { join, resolve } from "node:path";
131
- var DEFAULT_CONFIG = {
132
- maxConcurrent: 10,
133
- defaults: {
134
- timeoutMs: 30000,
135
- memoryLimit: "512m",
136
- cpuLimit: 1,
137
- network: "none",
138
- sandboxSize: "512m",
139
- tmpSize: "256m"
140
- },
141
- network: {
142
- whitelist: [],
143
- blacklist: []
144
- },
145
- cleanup: {
146
- autoPrune: true,
147
- maxContainerAgeMs: 3600000
148
- },
149
- dependencies: {},
150
- debug: false
151
10
  };
152
- function loadConfig(cwd) {
153
- const searchPaths = [
154
- join(resolve(cwd ?? process.cwd()), "isol8.config.json"),
155
- join(homedir(), ".isol8", "config.json")
156
- ];
157
- for (const configPath of searchPaths) {
158
- if (existsSync(configPath)) {
159
- const raw = readFileSync(configPath, "utf-8");
160
- const parsed = JSON.parse(raw);
161
- return mergeConfig(DEFAULT_CONFIG, parsed);
162
- }
163
- }
164
- return { ...DEFAULT_CONFIG };
165
- }
166
- function mergeConfig(defaults, overrides) {
167
- return {
168
- maxConcurrent: overrides.maxConcurrent ?? defaults.maxConcurrent,
169
- defaults: {
170
- ...defaults.defaults,
171
- ...overrides.defaults
172
- },
173
- network: {
174
- whitelist: overrides.network?.whitelist ?? defaults.network.whitelist,
175
- blacklist: overrides.network?.blacklist ?? defaults.network.blacklist
11
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
12
+
13
+ // src/runtime/adapter.ts
14
+ var adapters, extensionMap, RuntimeRegistry;
15
+ var init_adapter = __esm(() => {
16
+ adapters = new Map;
17
+ extensionMap = new Map;
18
+ RuntimeRegistry = {
19
+ register(adapter, aliases = []) {
20
+ adapters.set(adapter.name, adapter);
21
+ extensionMap.set(adapter.getFileExtension(), adapter);
22
+ for (const ext of aliases) {
23
+ extensionMap.set(ext, adapter);
24
+ }
176
25
  },
177
- cleanup: {
178
- ...defaults.cleanup,
179
- ...overrides.cleanup
26
+ get(name) {
27
+ const adapter = adapters.get(name);
28
+ if (!adapter) {
29
+ throw new Error(`Unknown runtime: "${name}". Available: ${[...adapters.keys()].join(", ")}`);
30
+ }
31
+ return adapter;
180
32
  },
181
- dependencies: {
182
- ...defaults.dependencies,
183
- ...overrides.dependencies
33
+ detect(filename) {
34
+ const ext = `.${filename.split(".").pop()}`;
35
+ const adapter = extensionMap.get(ext);
36
+ if (!adapter) {
37
+ throw new Error(`Cannot detect runtime for "${filename}". Known extensions: ${[...extensionMap.keys()].join(", ")}`);
38
+ }
39
+ return adapter;
184
40
  },
185
- debug: overrides.debug ?? defaults.debug
186
- };
187
- }
188
- // src/engine/docker.ts
189
- import { randomUUID } from "node:crypto";
190
- import { PassThrough } from "node:stream";
191
- import Docker from "dockerode";
192
-
193
- // src/runtime/adapter.ts
194
- var adapters = new Map;
195
- var extensionMap = new Map;
196
- var RuntimeRegistry = {
197
- register(adapter, aliases = []) {
198
- adapters.set(adapter.name, adapter);
199
- extensionMap.set(adapter.getFileExtension(), adapter);
200
- for (const ext of aliases) {
201
- extensionMap.set(ext, adapter);
202
- }
203
- },
204
- get(name) {
205
- const adapter = adapters.get(name);
206
- if (!adapter) {
207
- throw new Error(`Unknown runtime: "${name}". Available: ${[...adapters.keys()].join(", ")}`);
208
- }
209
- return adapter;
210
- },
211
- detect(filename) {
212
- const ext = `.${filename.split(".").pop()}`;
213
- const adapter = extensionMap.get(ext);
214
- if (!adapter) {
215
- throw new Error(`Cannot detect runtime for "${filename}". Known extensions: ${[...extensionMap.keys()].join(", ")}`);
41
+ list() {
42
+ return [...adapters.values()];
216
43
  }
217
- return adapter;
218
- },
219
- list() {
220
- return [...adapters.values()];
221
- }
222
- };
44
+ };
45
+ });
223
46
 
224
47
  // src/runtime/adapters/bash.ts
225
- var bashAdapter = {
226
- name: "bash",
227
- image: "isol8:bash",
228
- getCommand(code, filePath) {
229
- if (filePath) {
230
- return ["bash", filePath];
231
- }
232
- return ["bash", "-c", code];
233
- },
234
- getFileExtension() {
235
- return ".sh";
236
- }
237
- };
48
+ var bashAdapter;
49
+ var init_bash = __esm(() => {
50
+ bashAdapter = {
51
+ name: "bash",
52
+ image: "isol8:bash",
53
+ getCommand(code, filePath) {
54
+ if (filePath) {
55
+ return ["bash", filePath];
56
+ }
57
+ return ["bash", "-c", code];
58
+ },
59
+ getFileExtension() {
60
+ return ".sh";
61
+ }
62
+ };
63
+ });
238
64
 
239
65
  // src/runtime/adapters/bun.ts
240
- var BunAdapter = {
241
- name: "bun",
242
- image: "isol8:bun",
243
- getCommand(code, filePath) {
244
- if (filePath) {
245
- return ["bun", "run", filePath];
246
- }
247
- return ["bun", "-e", code];
248
- },
249
- getFileExtension() {
250
- return ".ts";
251
- }
252
- };
66
+ var BunAdapter;
67
+ var init_bun = __esm(() => {
68
+ BunAdapter = {
69
+ name: "bun",
70
+ image: "isol8:bun",
71
+ getCommand(code, filePath) {
72
+ if (filePath) {
73
+ return ["bun", "run", filePath];
74
+ }
75
+ return ["bun", "-e", code];
76
+ },
77
+ getFileExtension() {
78
+ return ".ts";
79
+ }
80
+ };
81
+ });
253
82
 
254
83
  // src/runtime/adapters/deno.ts
255
- var DenoAdapter = {
256
- name: "deno",
257
- image: "isol8:deno",
258
- getCommand(_code, filePath) {
259
- if (!filePath) {
260
- throw new Error("Deno adapter requires a file path — inline code is not supported.");
261
- }
262
- return [
263
- "deno",
264
- "run",
265
- "--allow-read=/sandbox,/tmp",
266
- "--allow-write=/sandbox,/tmp",
267
- "--allow-env",
268
- "--allow-net",
269
- filePath
270
- ];
271
- },
272
- getFileExtension() {
273
- return ".mts";
274
- }
275
- };
84
+ var DenoAdapter;
85
+ var init_deno = __esm(() => {
86
+ DenoAdapter = {
87
+ name: "deno",
88
+ image: "isol8:deno",
89
+ getCommand(_code, filePath) {
90
+ if (!filePath) {
91
+ throw new Error("Deno adapter requires a file path — inline code is not supported.");
92
+ }
93
+ return [
94
+ "deno",
95
+ "run",
96
+ "--allow-read=/sandbox,/tmp",
97
+ "--allow-write=/sandbox,/tmp",
98
+ "--allow-env",
99
+ "--allow-net",
100
+ filePath
101
+ ];
102
+ },
103
+ getFileExtension() {
104
+ return ".mts";
105
+ }
106
+ };
107
+ });
276
108
 
277
109
  // src/runtime/adapters/node.ts
278
- var NodeAdapter = {
279
- name: "node",
280
- image: "isol8:node",
281
- getCommand(code, filePath) {
282
- if (filePath) {
283
- return ["node", filePath];
284
- }
285
- return ["node", "-e", code];
286
- },
287
- getFileExtension() {
288
- return ".mjs";
289
- }
290
- };
110
+ var NodeAdapter;
111
+ var init_node = __esm(() => {
112
+ NodeAdapter = {
113
+ name: "node",
114
+ image: "isol8:node",
115
+ getCommand(code, filePath) {
116
+ if (filePath) {
117
+ return ["node", filePath];
118
+ }
119
+ return ["node", "-e", code];
120
+ },
121
+ getFileExtension() {
122
+ return ".mjs";
123
+ }
124
+ };
125
+ });
291
126
 
292
127
  // src/runtime/adapters/python.ts
293
- var PythonAdapter = {
294
- name: "python",
295
- image: "isol8:python",
296
- getCommand(code, filePath) {
297
- if (filePath) {
298
- return ["python3", filePath];
299
- }
300
- return ["python3", "-c", code];
301
- },
302
- getFileExtension() {
303
- return ".py";
304
- }
305
- };
128
+ var PythonAdapter;
129
+ var init_python = __esm(() => {
130
+ PythonAdapter = {
131
+ name: "python",
132
+ image: "isol8:python",
133
+ getCommand(code, filePath) {
134
+ if (filePath) {
135
+ return ["python3", filePath];
136
+ }
137
+ return ["python3", "-c", code];
138
+ },
139
+ getFileExtension() {
140
+ return ".py";
141
+ }
142
+ };
143
+ });
306
144
 
307
145
  // src/runtime/index.ts
308
- RuntimeRegistry.register(PythonAdapter);
309
- RuntimeRegistry.register(NodeAdapter, [".js", ".cjs"]);
310
- RuntimeRegistry.register(BunAdapter);
311
- RuntimeRegistry.register(bashAdapter);
312
- RuntimeRegistry.register(DenoAdapter);
146
+ var exports_runtime = {};
147
+ __export(exports_runtime, {
148
+ bashAdapter: () => bashAdapter,
149
+ RuntimeRegistry: () => RuntimeRegistry,
150
+ PythonAdapter: () => PythonAdapter,
151
+ NodeAdapter: () => NodeAdapter,
152
+ DenoAdapter: () => DenoAdapter,
153
+ BunAdapter: () => BunAdapter
154
+ });
155
+ var init_runtime = __esm(() => {
156
+ init_adapter();
157
+ init_bash();
158
+ init_bun();
159
+ init_deno();
160
+ init_node();
161
+ init_python();
162
+ init_adapter();
163
+ init_bash();
164
+ init_bun();
165
+ init_deno();
166
+ init_node();
167
+ init_python();
168
+ RuntimeRegistry.register(PythonAdapter);
169
+ RuntimeRegistry.register(NodeAdapter, [".js", ".cjs"]);
170
+ RuntimeRegistry.register(BunAdapter);
171
+ RuntimeRegistry.register(bashAdapter);
172
+ RuntimeRegistry.register(DenoAdapter);
173
+ });
313
174
 
314
175
  // src/utils/logger.ts
315
176
  class Logger {
@@ -332,7 +193,10 @@ class Logger {
332
193
  console.error("[ERROR]", ...args);
333
194
  }
334
195
  }
335
- var logger = new Logger;
196
+ var logger;
197
+ var init_logger = __esm(() => {
198
+ logger = new Logger;
199
+ });
336
200
 
337
201
  // src/engine/concurrency.ts
338
202
  class Semaphore {
@@ -475,6 +339,9 @@ class ContainerPool {
475
339
  this.pendingReplenishments.add(promise);
476
340
  }
477
341
  }
342
+ var init_pool = __esm(() => {
343
+ init_logger();
344
+ });
478
345
 
479
346
  // src/engine/utils.ts
480
347
  function parseMemoryLimit(limit) {
@@ -567,6 +434,13 @@ function extractFromTar(tarBuffer, targetPath) {
567
434
  }
568
435
 
569
436
  // src/engine/docker.ts
437
+ var exports_docker = {};
438
+ __export(exports_docker, {
439
+ DockerIsol8: () => DockerIsol8
440
+ });
441
+ import { randomUUID } from "node:crypto";
442
+ import { PassThrough } from "node:stream";
443
+ import Docker from "dockerode";
570
444
  async function writeFileViaExec(container, filePath, content) {
571
445
  const data = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
572
446
  const b64 = data.toString("base64");
@@ -609,11 +483,6 @@ async function readFileViaExec(container, filePath) {
609
483
  const b64Output = Buffer.concat(chunks).toString("utf-8").trim();
610
484
  return Buffer.from(b64Output, "base64");
611
485
  }
612
- var SANDBOX_WORKDIR = "/sandbox";
613
- var MAX_OUTPUT_BYTES = 1024 * 1024;
614
- var PROXY_PORT = 8118;
615
- var PROXY_STARTUP_TIMEOUT_MS = 5000;
616
- var PROXY_POLL_INTERVAL_MS = 100;
617
486
  async function startProxy(container, networkFilter) {
618
487
  const envParts = [];
619
488
  if (networkFilter) {
@@ -1256,35 +1125,348 @@ class DockerIsol8 {
1256
1125
  return { removed, failed, errors };
1257
1126
  }
1258
1127
  }
1259
- // src/server/index.ts
1260
- import { Hono } from "hono";
1128
+ var SANDBOX_WORKDIR = "/sandbox", MAX_OUTPUT_BYTES, PROXY_PORT = 8118, PROXY_STARTUP_TIMEOUT_MS = 5000, PROXY_POLL_INTERVAL_MS = 100;
1129
+ var init_docker = __esm(() => {
1130
+ init_runtime();
1131
+ init_logger();
1132
+ init_pool();
1133
+ MAX_OUTPUT_BYTES = 1024 * 1024;
1134
+ });
1261
1135
 
1262
- // src/server/auth.ts
1263
- function authMiddleware(apiKey) {
1264
- return async (c, next) => {
1265
- if (c.req.path === "/health") {
1266
- return next();
1267
- }
1268
- const authHeader = c.req.header("Authorization");
1269
- if (!authHeader) {
1270
- return c.json({ error: "Missing Authorization header" }, 401);
1271
- }
1272
- const token = authHeader.replace(/^Bearer\s+/i, "");
1273
- if (token !== apiKey) {
1274
- return c.json({ error: "Invalid API key" }, 403);
1275
- }
1136
+ // src/client/remote.ts
1137
+ class RemoteIsol8 {
1138
+ host;
1139
+ apiKey;
1140
+ sessionId;
1141
+ isol8Options;
1142
+ constructor(options, isol8Options) {
1143
+ this.host = options.host.replace(/\/$/, "");
1144
+ this.apiKey = options.apiKey;
1145
+ this.sessionId = options.sessionId;
1146
+ this.isol8Options = isol8Options;
1147
+ }
1148
+ async start() {
1149
+ const res = await this.fetch("/health");
1150
+ if (!res.ok) {
1151
+ throw new Error(`Remote server health check failed: ${res.status}`);
1152
+ }
1153
+ }
1154
+ async stop() {
1155
+ if (this.sessionId) {
1156
+ await this.fetch(`/session/${this.sessionId}`, { method: "DELETE" });
1157
+ }
1158
+ }
1159
+ async execute(req) {
1160
+ const res = await this.fetch("/execute", {
1161
+ method: "POST",
1162
+ body: JSON.stringify({
1163
+ request: req,
1164
+ options: this.isol8Options,
1165
+ sessionId: this.sessionId
1166
+ })
1167
+ });
1168
+ if (!res.ok) {
1169
+ const body = await res.json().catch(() => ({}));
1170
+ throw new Error(`Execution failed: ${body.error ?? res.statusText}`);
1171
+ }
1172
+ return res.json();
1173
+ }
1174
+ async* executeStream(req) {
1175
+ const res = await this.fetch("/execute/stream", {
1176
+ method: "POST",
1177
+ body: JSON.stringify({
1178
+ request: req,
1179
+ options: this.isol8Options,
1180
+ sessionId: this.sessionId
1181
+ })
1182
+ });
1183
+ if (!res.ok) {
1184
+ const body = await res.json().catch(() => ({}));
1185
+ throw new Error(`Stream failed: ${body.error ?? res.statusText}`);
1186
+ }
1187
+ if (!res.body) {
1188
+ throw new Error("No response body for streaming");
1189
+ }
1190
+ const reader = res.body.getReader();
1191
+ const decoder = new TextDecoder;
1192
+ let buffer = "";
1193
+ try {
1194
+ while (true) {
1195
+ const { done, value } = await reader.read();
1196
+ if (done) {
1197
+ break;
1198
+ }
1199
+ buffer += decoder.decode(value, { stream: true });
1200
+ const lines = buffer.split(`
1201
+ `);
1202
+ buffer = lines.pop() ?? "";
1203
+ for (const line of lines) {
1204
+ if (line.startsWith("data: ")) {
1205
+ const json = line.slice(6).trim();
1206
+ if (json) {
1207
+ yield JSON.parse(json);
1208
+ }
1209
+ }
1210
+ }
1211
+ }
1212
+ if (buffer.startsWith("data: ")) {
1213
+ const json = buffer.slice(6).trim();
1214
+ if (json) {
1215
+ yield JSON.parse(json);
1216
+ }
1217
+ }
1218
+ } finally {
1219
+ reader.releaseLock();
1220
+ }
1221
+ }
1222
+ async putFile(path, content) {
1223
+ if (!this.sessionId) {
1224
+ throw new Error("File operations require a sessionId (persistent mode)");
1225
+ }
1226
+ const base64 = typeof content === "string" ? Buffer.from(content).toString("base64") : content.toString("base64");
1227
+ const res = await this.fetch("/file", {
1228
+ method: "POST",
1229
+ body: JSON.stringify({
1230
+ sessionId: this.sessionId,
1231
+ path,
1232
+ content: base64
1233
+ })
1234
+ });
1235
+ if (!res.ok) {
1236
+ throw new Error(`File upload failed: ${res.statusText}`);
1237
+ }
1238
+ }
1239
+ async getFile(path) {
1240
+ if (!this.sessionId) {
1241
+ throw new Error("File operations require a sessionId (persistent mode)");
1242
+ }
1243
+ const params = new URLSearchParams({ sessionId: this.sessionId, path });
1244
+ const res = await this.fetch(`/file?${params}`);
1245
+ if (!res.ok) {
1246
+ throw new Error(`File download failed: ${res.statusText}`);
1247
+ }
1248
+ const body = await res.json();
1249
+ return Buffer.from(body.content, "base64");
1250
+ }
1251
+ async fetch(path, init) {
1252
+ return globalThis.fetch(`${this.host}${path}`, {
1253
+ ...init,
1254
+ headers: {
1255
+ "Content-Type": "application/json",
1256
+ Authorization: `Bearer ${this.apiKey}`,
1257
+ ...init?.headers ?? {}
1258
+ }
1259
+ });
1260
+ }
1261
+ }
1262
+ // src/config.ts
1263
+ import { existsSync, readFileSync } from "node:fs";
1264
+ import { homedir } from "node:os";
1265
+ import { join, resolve } from "node:path";
1266
+ var DEFAULT_CONFIG = {
1267
+ maxConcurrent: 10,
1268
+ defaults: {
1269
+ timeoutMs: 30000,
1270
+ memoryLimit: "512m",
1271
+ cpuLimit: 1,
1272
+ network: "none",
1273
+ sandboxSize: "512m",
1274
+ tmpSize: "256m"
1275
+ },
1276
+ network: {
1277
+ whitelist: [],
1278
+ blacklist: []
1279
+ },
1280
+ cleanup: {
1281
+ autoPrune: true,
1282
+ maxContainerAgeMs: 3600000
1283
+ },
1284
+ dependencies: {},
1285
+ debug: false
1286
+ };
1287
+ function loadConfig(cwd) {
1288
+ const searchPaths = [
1289
+ join(resolve(cwd ?? process.cwd()), "isol8.config.json"),
1290
+ join(homedir(), ".isol8", "config.json")
1291
+ ];
1292
+ for (const configPath of searchPaths) {
1293
+ if (existsSync(configPath)) {
1294
+ const raw = readFileSync(configPath, "utf-8");
1295
+ const parsed = JSON.parse(raw);
1296
+ return mergeConfig(DEFAULT_CONFIG, parsed);
1297
+ }
1298
+ }
1299
+ return { ...DEFAULT_CONFIG };
1300
+ }
1301
+ function mergeConfig(defaults, overrides) {
1302
+ return {
1303
+ maxConcurrent: overrides.maxConcurrent ?? defaults.maxConcurrent,
1304
+ defaults: {
1305
+ ...defaults.defaults,
1306
+ ...overrides.defaults
1307
+ },
1308
+ network: {
1309
+ whitelist: overrides.network?.whitelist ?? defaults.network.whitelist,
1310
+ blacklist: overrides.network?.blacklist ?? defaults.network.blacklist
1311
+ },
1312
+ cleanup: {
1313
+ ...defaults.cleanup,
1314
+ ...overrides.cleanup
1315
+ },
1316
+ dependencies: {
1317
+ ...defaults.dependencies,
1318
+ ...overrides.dependencies
1319
+ },
1320
+ debug: overrides.debug ?? defaults.debug
1321
+ };
1322
+ }
1323
+
1324
+ // src/index.ts
1325
+ init_docker();
1326
+ init_runtime();
1327
+
1328
+ // src/server/index.ts
1329
+ import { Hono } from "hono";
1330
+ // package.json
1331
+ var package_default = {
1332
+ name: "isol8",
1333
+ version: "0.6.0",
1334
+ description: "Secure code execution engine for AI agents",
1335
+ author: "Illusion47586",
1336
+ license: "MIT",
1337
+ repository: {
1338
+ type: "git",
1339
+ url: "https://github.com/Illusion47586/isol8.git"
1340
+ },
1341
+ homepage: "https://github.com/Illusion47586/isol8",
1342
+ bugs: {
1343
+ url: "https://github.com/Illusion47586/isol8/issues"
1344
+ },
1345
+ keywords: [
1346
+ "sandbox",
1347
+ "docker",
1348
+ "code-execution",
1349
+ "isolation",
1350
+ "security",
1351
+ "ai-agents",
1352
+ "container",
1353
+ "runtime"
1354
+ ],
1355
+ type: "module",
1356
+ main: "./dist/index.js",
1357
+ types: "./dist/index.d.ts",
1358
+ exports: {
1359
+ ".": {
1360
+ import: "./dist/index.js",
1361
+ types: "./dist/index.d.ts"
1362
+ },
1363
+ "./schema": "./schema/isol8.config.schema.json"
1364
+ },
1365
+ bin: {
1366
+ isol8: "./dist/cli.js"
1367
+ },
1368
+ scripts: {
1369
+ dev: "bun run src/cli.ts",
1370
+ build: "bun run scripts/build.ts",
1371
+ "build:server": "bun run scripts/build-server.ts",
1372
+ "build:server:all": "bun run scripts/build-server.ts --all",
1373
+ test: "bun test",
1374
+ "lint:check": "ultracite check",
1375
+ "lint:fix": "ultracite fix",
1376
+ bench: "bunx tsx benchmarks/spawn.ts",
1377
+ "bench:pool": "bunx tsx benchmarks/spawn-pool.ts",
1378
+ "bench:detailed": "bunx tsx benchmarks/spawn-detailed.ts",
1379
+ "docs:dev": "cd docs && mint dev",
1380
+ "docs:validate": "cd docs && mint validate",
1381
+ "docs:broken-links": "cd docs && mint broken-links",
1382
+ schema: "ts-json-schema-generator --path src/types.ts --type Isol8UserConfig --tsconfig tsconfig.json -o schema/isol8.config.schema.json && ultracite fix schema/isol8.config.schema.json",
1383
+ "publish:alpha": "bun run build && bun publish --tag alpha --access public --ignore-scripts",
1384
+ prepare: "simple-git-hooks"
1385
+ },
1386
+ dependencies: {
1387
+ commander: "^14.0.3",
1388
+ dockerode: "^4.0.9",
1389
+ hono: "^4.11.9",
1390
+ ora: "^9.3.0"
1391
+ },
1392
+ devDependencies: {
1393
+ "@biomejs/biome": "^2.3.15",
1394
+ "@semantic-release/changelog": "^6.0.3",
1395
+ "@semantic-release/git": "^10.0.1",
1396
+ "@semantic-release/github": "^12.0.6",
1397
+ "@semantic-release/npm": "^13.1.4",
1398
+ "@types/bun": "latest",
1399
+ "@types/dockerode": "^4.0.1",
1400
+ "@types/node": "^25.2.3",
1401
+ "lint-staged": "^16.2.7",
1402
+ mint: "^4.2.348",
1403
+ "semantic-release": "^25.0.3",
1404
+ "simple-git-hooks": "^2.13.1",
1405
+ "ts-json-schema-generator": "^2.5.0",
1406
+ typescript: "^5.9.3",
1407
+ ultracite: "^7.2.0"
1408
+ },
1409
+ files: [
1410
+ "dist/cli.js",
1411
+ "dist/index.js",
1412
+ "dist/src",
1413
+ "dist/docker",
1414
+ "schema",
1415
+ "README.md",
1416
+ "LICENSE"
1417
+ ],
1418
+ jsonValidation: [
1419
+ {
1420
+ fileMatch: "isol8.config.json",
1421
+ url: "./schema/isol8.config.schema.json"
1422
+ }
1423
+ ],
1424
+ "simple-git-hooks": {
1425
+ "pre-commit": "bun run lint-staged"
1426
+ },
1427
+ "lint-staged": {
1428
+ "*.{ts,tsx}": [
1429
+ "ultracite fix",
1430
+ "bash -c 'bunx tsc --noEmit -p tsconfig.json'"
1431
+ ],
1432
+ "src/types.ts": [
1433
+ "bash -c 'bun run schema'",
1434
+ "git add schema/isol8.config.schema.json"
1435
+ ]
1436
+ }
1437
+ };
1438
+
1439
+ // src/version.ts
1440
+ var VERSION = package_default.version;
1441
+
1442
+ // src/server/auth.ts
1443
+ function authMiddleware(apiKey) {
1444
+ return async (c, next) => {
1445
+ if (c.req.path === "/health") {
1446
+ return next();
1447
+ }
1448
+ const authHeader = c.req.header("Authorization");
1449
+ if (!authHeader) {
1450
+ return c.json({ error: "Missing Authorization header" }, 401);
1451
+ }
1452
+ const token = authHeader.replace(/^Bearer\s+/i, "");
1453
+ if (token !== apiKey) {
1454
+ return c.json({ error: "Invalid API key" }, 403);
1455
+ }
1276
1456
  return next();
1277
1457
  };
1278
1458
  }
1279
1459
 
1280
1460
  // src/server/index.ts
1281
1461
  var sessions = new Map;
1282
- function createServer(options) {
1462
+ async function createServer(options) {
1463
+ const { DockerIsol8: DockerIsol82 } = await Promise.resolve().then(() => (init_docker(), exports_docker));
1464
+ await Promise.resolve().then(() => (init_runtime(), exports_runtime));
1283
1465
  const config = loadConfig();
1284
1466
  const app = new Hono;
1285
1467
  const globalSemaphore = new Semaphore(config.maxConcurrent);
1286
1468
  app.use("*", authMiddleware(options.apiKey));
1287
- app.get("/health", (c) => c.json({ status: "ok", version: "0.1.0" }));
1469
+ app.get("/health", (c) => c.json({ status: "ok", version: VERSION }));
1288
1470
  app.post("/execute", async (c) => {
1289
1471
  const body = await c.req.json();
1290
1472
  const engineOptions = {
@@ -1304,12 +1486,12 @@ function createServer(options) {
1304
1486
  engine = session.engine;
1305
1487
  session.lastAccessedAt = Date.now();
1306
1488
  } else {
1307
- engine = new DockerIsol8(engineOptions, config.maxConcurrent);
1489
+ engine = new DockerIsol82(engineOptions, config.maxConcurrent);
1308
1490
  await engine.start();
1309
1491
  sessions.set(body.sessionId, { engine, lastAccessedAt: Date.now() });
1310
1492
  }
1311
1493
  } else {
1312
- engine = new DockerIsol8(engineOptions, config.maxConcurrent);
1494
+ engine = new DockerIsol82(engineOptions, config.maxConcurrent);
1313
1495
  await engine.start();
1314
1496
  }
1315
1497
  try {
@@ -1341,7 +1523,7 @@ function createServer(options) {
1341
1523
  ...body.options,
1342
1524
  mode: "ephemeral"
1343
1525
  };
1344
- const engine = new DockerIsol8(engineOptions, config.maxConcurrent);
1526
+ const engine = new DockerIsol82(engineOptions, config.maxConcurrent);
1345
1527
  await engine.start();
1346
1528
  const encoder = new TextEncoder;
1347
1529
  const stream = new ReadableStream({
@@ -1430,113 +1612,6 @@ function createServer(options) {
1430
1612
  port: options.port
1431
1613
  };
1432
1614
  }
1433
- // package.json
1434
- var package_default = {
1435
- name: "isol8",
1436
- version: "0.5.0",
1437
- description: "Secure code execution engine for AI agents",
1438
- author: "Illusion47586",
1439
- license: "MIT",
1440
- repository: {
1441
- type: "git",
1442
- url: "https://github.com/Illusion47586/isol8.git"
1443
- },
1444
- homepage: "https://github.com/Illusion47586/isol8",
1445
- bugs: {
1446
- url: "https://github.com/Illusion47586/isol8/issues"
1447
- },
1448
- keywords: [
1449
- "sandbox",
1450
- "docker",
1451
- "code-execution",
1452
- "isolation",
1453
- "security",
1454
- "ai-agents",
1455
- "container",
1456
- "runtime"
1457
- ],
1458
- type: "module",
1459
- main: "./dist/index.js",
1460
- types: "./dist/index.d.ts",
1461
- exports: {
1462
- ".": {
1463
- import: "./dist/index.js",
1464
- types: "./dist/index.d.ts"
1465
- },
1466
- "./schema": "./schema/isol8.config.schema.json"
1467
- },
1468
- bin: {
1469
- isol8: "./dist/cli.js"
1470
- },
1471
- scripts: {
1472
- dev: "bun run src/cli.ts",
1473
- build: "bun run scripts/build.ts",
1474
- test: "bun test",
1475
- "lint:check": "ultracite check",
1476
- "lint:fix": "ultracite fix",
1477
- bench: "bunx tsx benchmarks/spawn.ts",
1478
- "bench:pool": "bunx tsx benchmarks/spawn-pool.ts",
1479
- "bench:detailed": "bunx tsx benchmarks/spawn-detailed.ts",
1480
- "docs:dev": "cd docs && mint dev",
1481
- "docs:validate": "cd docs && mint validate",
1482
- "docs:broken-links": "cd docs && mint broken-links",
1483
- schema: "ts-json-schema-generator --path src/types.ts --type Isol8UserConfig --tsconfig tsconfig.json -o schema/isol8.config.schema.json && ultracite fix schema/isol8.config.schema.json",
1484
- "publish:alpha": "bun run build && bun publish --tag alpha --access public --ignore-scripts",
1485
- prepare: "simple-git-hooks"
1486
- },
1487
- dependencies: {
1488
- commander: "^14.0.3",
1489
- dockerode: "^4.0.9",
1490
- hono: "^4.11.9",
1491
- ora: "^9.3.0"
1492
- },
1493
- devDependencies: {
1494
- "@biomejs/biome": "^2.3.15",
1495
- "@semantic-release/changelog": "^6.0.3",
1496
- "@semantic-release/git": "^10.0.1",
1497
- "@semantic-release/github": "^12.0.6",
1498
- "@semantic-release/npm": "^13.1.4",
1499
- "@types/bun": "latest",
1500
- "@types/dockerode": "^4.0.1",
1501
- "@types/node": "^25.2.3",
1502
- "lint-staged": "^16.2.7",
1503
- mint: "^4.2.348",
1504
- "semantic-release": "^25.0.3",
1505
- "simple-git-hooks": "^2.13.1",
1506
- "ts-json-schema-generator": "^2.5.0",
1507
- typescript: "^5.9.3",
1508
- ultracite: "^7.2.0"
1509
- },
1510
- files: [
1511
- "dist",
1512
- "schema",
1513
- "docker",
1514
- "README.md",
1515
- "LICENSE"
1516
- ],
1517
- jsonValidation: [
1518
- {
1519
- fileMatch: "isol8.config.json",
1520
- url: "./schema/isol8.config.schema.json"
1521
- }
1522
- ],
1523
- "simple-git-hooks": {
1524
- "pre-commit": "bun run lint-staged"
1525
- },
1526
- "lint-staged": {
1527
- "*.{ts,tsx}": [
1528
- "ultracite fix",
1529
- "bash -c 'bunx tsc --noEmit -p tsconfig.json'"
1530
- ],
1531
- "src/types.ts": [
1532
- "bash -c 'bun run schema'",
1533
- "git add schema/isol8.config.schema.json"
1534
- ]
1535
- }
1536
- };
1537
-
1538
- // src/version.ts
1539
- var VERSION = package_default.version;
1540
1615
  export {
1541
1616
  loadConfig,
1542
1617
  createServer,
@@ -1551,4 +1626,4 @@ export {
1551
1626
  BunAdapter
1552
1627
  };
1553
1628
 
1554
- //# debugId=F7892F8784782B0464756E2164756E21
1629
+ //# debugId=BE9F771BA94691E364756E2164756E21