isol8 0.12.0 → 0.12.2
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/cli.js
CHANGED
|
@@ -6929,6 +6929,11 @@ var require_utils2 = __commonJS((exports, module) => {
|
|
|
6929
6929
|
};
|
|
6930
6930
|
});
|
|
6931
6931
|
|
|
6932
|
+
// node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node
|
|
6933
|
+
var require_sshcrypto = __commonJS((exports, module) => {
|
|
6934
|
+
module.exports = __require("./sshcrypto-0209sx47.node");
|
|
6935
|
+
});
|
|
6936
|
+
|
|
6932
6937
|
// node_modules/ssh2/lib/protocol/crypto/poly1305.js
|
|
6933
6938
|
var require_poly1305 = __commonJS((exports, module) => {
|
|
6934
6939
|
var __dirname = "/home/runner/work/isol8/isol8/node_modules/ssh2/lib/protocol/crypto", __filename = "/home/runner/work/isol8/isol8/node_modules/ssh2/lib/protocol/crypto/poly1305.js";
|
|
@@ -7415,7 +7420,7 @@ var require_crypto = __commonJS((exports, module) => {
|
|
|
7415
7420
|
var ChaChaPolyDecipher;
|
|
7416
7421
|
var GenericDecipher;
|
|
7417
7422
|
try {
|
|
7418
|
-
binding = (
|
|
7423
|
+
binding = require_sshcrypto();
|
|
7419
7424
|
({
|
|
7420
7425
|
AESGCMCipher,
|
|
7421
7426
|
ChaChaPolyCipher,
|
|
@@ -55587,13 +55592,39 @@ function validatePackageName(name) {
|
|
|
55587
55592
|
}
|
|
55588
55593
|
|
|
55589
55594
|
// src/engine/image-builder.ts
|
|
55595
|
+
var exports_image_builder = {};
|
|
55596
|
+
__export(exports_image_builder, {
|
|
55597
|
+
normalizePackages: () => normalizePackages,
|
|
55598
|
+
imageExists: () => imageExists,
|
|
55599
|
+
getCustomImageTag: () => getCustomImageTag,
|
|
55600
|
+
ensureImages: () => ensureImages,
|
|
55601
|
+
buildCustomImages: () => buildCustomImages,
|
|
55602
|
+
buildCustomImage: () => buildCustomImage,
|
|
55603
|
+
buildBaseImages: () => buildBaseImages
|
|
55604
|
+
});
|
|
55590
55605
|
import { createHash as createHash2 } from "node:crypto";
|
|
55591
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
55592
|
-
import { join as join3 } from "node:path";
|
|
55606
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
|
|
55607
|
+
import { dirname, join as join3 } from "node:path";
|
|
55593
55608
|
function resolveDockerDir() {
|
|
55594
|
-
const
|
|
55595
|
-
if (existsSync3(
|
|
55596
|
-
return
|
|
55609
|
+
const fromExec = join3(dirname(process.execPath), "docker");
|
|
55610
|
+
if (existsSync3(fromExec) && statSync2(fromExec).isDirectory()) {
|
|
55611
|
+
return fromExec;
|
|
55612
|
+
}
|
|
55613
|
+
if (!import.meta.url.includes("$bunfs")) {
|
|
55614
|
+
const fromBundled = new URL("./docker", import.meta.url).pathname;
|
|
55615
|
+
if (existsSync3(fromBundled)) {
|
|
55616
|
+
return fromBundled;
|
|
55617
|
+
}
|
|
55618
|
+
}
|
|
55619
|
+
if (!import.meta.url.includes("$bunfs")) {
|
|
55620
|
+
const fromDev = new URL("../../docker", import.meta.url).pathname;
|
|
55621
|
+
if (existsSync3(fromDev)) {
|
|
55622
|
+
return fromDev;
|
|
55623
|
+
}
|
|
55624
|
+
}
|
|
55625
|
+
const fromCwd = join3(process.cwd(), "docker");
|
|
55626
|
+
if (existsSync3(fromCwd)) {
|
|
55627
|
+
return fromCwd;
|
|
55597
55628
|
}
|
|
55598
55629
|
return new URL("../../docker", import.meta.url).pathname;
|
|
55599
55630
|
}
|
|
@@ -55645,8 +55676,9 @@ async function removeImage(docker, imageId) {
|
|
|
55645
55676
|
logger.debug(`[ImageBuilder] Could not remove image ${imageId.slice(0, 12)}: ${err}`);
|
|
55646
55677
|
}
|
|
55647
55678
|
}
|
|
55648
|
-
async function buildBaseImages(docker, onProgress, force = false) {
|
|
55649
|
-
const
|
|
55679
|
+
async function buildBaseImages(docker, onProgress, force = false, onlyRuntimes) {
|
|
55680
|
+
const allRuntimes = RuntimeRegistry.list();
|
|
55681
|
+
const runtimes = onlyRuntimes ? allRuntimes.filter((r) => onlyRuntimes.includes(r.name)) : allRuntimes;
|
|
55650
55682
|
const dockerHash = computeDockerDirHash();
|
|
55651
55683
|
logger.debug(`[ImageBuilder] Docker directory hash: ${dockerHash.slice(0, 16)}...`);
|
|
55652
55684
|
for (const adapter of runtimes) {
|
|
@@ -55796,6 +55828,26 @@ ${installCmd}
|
|
|
55796
55828
|
}
|
|
55797
55829
|
onProgress?.({ runtime, status: "done" });
|
|
55798
55830
|
}
|
|
55831
|
+
async function imageExists(docker, imageName) {
|
|
55832
|
+
try {
|
|
55833
|
+
await docker.getImage(imageName).inspect();
|
|
55834
|
+
return true;
|
|
55835
|
+
} catch {
|
|
55836
|
+
return false;
|
|
55837
|
+
}
|
|
55838
|
+
}
|
|
55839
|
+
async function ensureImages(docker, onProgress) {
|
|
55840
|
+
const runtimes = RuntimeRegistry.list();
|
|
55841
|
+
const missing = [];
|
|
55842
|
+
for (const adapter of runtimes) {
|
|
55843
|
+
if (!await imageExists(docker, adapter.image)) {
|
|
55844
|
+
missing.push(adapter.name);
|
|
55845
|
+
}
|
|
55846
|
+
}
|
|
55847
|
+
if (missing.length > 0) {
|
|
55848
|
+
await buildBaseImages(docker, onProgress, false, missing);
|
|
55849
|
+
}
|
|
55850
|
+
}
|
|
55799
55851
|
var DOCKERFILE_DIR, LABELS, DOCKER_BUILD_FILES;
|
|
55800
55852
|
var init_image_builder = __esm(() => {
|
|
55801
55853
|
init_runtime();
|
|
@@ -56694,6 +56746,25 @@ class DockerIsol8 {
|
|
|
56694
56746
|
resolvedImage = legacyCustomTag;
|
|
56695
56747
|
} catch {}
|
|
56696
56748
|
}
|
|
56749
|
+
try {
|
|
56750
|
+
await this.docker.getImage(resolvedImage).inspect();
|
|
56751
|
+
} catch {
|
|
56752
|
+
logger.debug(`[ImageBuilder] Image ${resolvedImage} not found. Building...`);
|
|
56753
|
+
const { buildBaseImages: buildBaseImages2, buildCustomImage: buildCustomImage2 } = await Promise.resolve().then(() => (init_image_builder(), exports_image_builder));
|
|
56754
|
+
if (resolvedImage !== adapter.image && normalizedDeps.length > 0) {
|
|
56755
|
+
try {
|
|
56756
|
+
await this.docker.getImage(adapter.image).inspect();
|
|
56757
|
+
} catch {
|
|
56758
|
+
logger.debug(`[ImageBuilder] Base image ${adapter.image} missing. Building...`);
|
|
56759
|
+
await buildBaseImages2(this.docker, undefined, false, [adapter.name]);
|
|
56760
|
+
}
|
|
56761
|
+
logger.debug(`[ImageBuilder] Building custom image for ${adapter.name}...`);
|
|
56762
|
+
await buildCustomImage2(this.docker, adapter.name, normalizedDeps);
|
|
56763
|
+
} else {
|
|
56764
|
+
logger.debug(`[ImageBuilder] Building base image for ${adapter.name}...`);
|
|
56765
|
+
await buildBaseImages2(this.docker, undefined, false, [adapter.name]);
|
|
56766
|
+
}
|
|
56767
|
+
}
|
|
56697
56768
|
this.imageCache.set(cacheKey, resolvedImage);
|
|
56698
56769
|
return resolvedImage;
|
|
56699
56770
|
}
|
|
@@ -57267,7 +57338,7 @@ var package_default;
|
|
|
57267
57338
|
var init_package = __esm(() => {
|
|
57268
57339
|
package_default = {
|
|
57269
57340
|
name: "isol8",
|
|
57270
|
-
version: "0.
|
|
57341
|
+
version: "0.12.1",
|
|
57271
57342
|
description: "Secure code execution engine for AI agents",
|
|
57272
57343
|
author: "Illusion47586",
|
|
57273
57344
|
license: "MIT",
|
|
@@ -63025,7 +63096,13 @@ async function downloadServerBinary(binaryPath) {
|
|
|
63025
63096
|
logger.debug(`[Serve] Download URL: ${url}`);
|
|
63026
63097
|
const spinner = ora(`Downloading isol8 server v${VERSION}...`).start();
|
|
63027
63098
|
try {
|
|
63028
|
-
|
|
63099
|
+
let response = await fetch(url, { redirect: "follow" });
|
|
63100
|
+
if (response.status === 404) {
|
|
63101
|
+
const fallbackUrl = `https://github.com/Illusion47586/isol8/releases/latest/download/${binaryName}`;
|
|
63102
|
+
logger.debug(`[Serve] Binary not found for v${VERSION}, trying latest from ${fallbackUrl}`);
|
|
63103
|
+
spinner.text = `v${VERSION} not found, downloading latest available version...`;
|
|
63104
|
+
response = await fetch(fallbackUrl, { redirect: "follow" });
|
|
63105
|
+
}
|
|
63029
63106
|
if (!response.ok) {
|
|
63030
63107
|
spinner.fail(`Failed to download server binary (HTTP ${response.status})`);
|
|
63031
63108
|
if (response.status === 404) {
|
|
@@ -63560,4 +63637,4 @@ if (!process.argv.slice(2).length) {
|
|
|
63560
63637
|
}
|
|
63561
63638
|
program2.parse();
|
|
63562
63639
|
|
|
63563
|
-
//# debugId=
|
|
63640
|
+
//# debugId=D193290D2EBA50ED64756E2164756E21
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
2
3
|
var __export = (target, all) => {
|
|
3
4
|
for (var name in all)
|
|
@@ -9,6 +10,7 @@ var __export = (target, all) => {
|
|
|
9
10
|
});
|
|
10
11
|
};
|
|
11
12
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
13
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
12
14
|
|
|
13
15
|
// src/runtime/adapter.ts
|
|
14
16
|
var adapters, extensionMap, RuntimeRegistry;
|
|
@@ -613,16 +615,161 @@ var init_default_seccomp_profile = __esm(() => {
|
|
|
613
615
|
});
|
|
614
616
|
});
|
|
615
617
|
|
|
618
|
+
// src/engine/utils.ts
|
|
619
|
+
var exports_utils = {};
|
|
620
|
+
__export(exports_utils, {
|
|
621
|
+
validatePackageName: () => validatePackageName,
|
|
622
|
+
truncateOutput: () => truncateOutput,
|
|
623
|
+
parseMemoryLimit: () => parseMemoryLimit,
|
|
624
|
+
maskSecrets: () => maskSecrets,
|
|
625
|
+
extractFromTar: () => extractFromTar,
|
|
626
|
+
createTarBuffer: () => createTarBuffer
|
|
627
|
+
});
|
|
628
|
+
function parseMemoryLimit(limit) {
|
|
629
|
+
const match = limit.match(/^(\d+(?:\.\d+)?)\s*([kmgt]?)b?$/i);
|
|
630
|
+
if (!match) {
|
|
631
|
+
throw new Error(`Invalid memory limit format: "${limit}". Use e.g. "512m", "1g".`);
|
|
632
|
+
}
|
|
633
|
+
const value = Number.parseFloat(match[1]);
|
|
634
|
+
const unit = (match[2] || "b").toLowerCase();
|
|
635
|
+
const multipliers = {
|
|
636
|
+
b: 1,
|
|
637
|
+
k: 1024,
|
|
638
|
+
m: 1024 ** 2,
|
|
639
|
+
g: 1024 ** 3,
|
|
640
|
+
t: 1024 ** 4
|
|
641
|
+
};
|
|
642
|
+
return Math.floor(value * (multipliers[unit] ?? 1));
|
|
643
|
+
}
|
|
644
|
+
function truncateOutput(output, maxBytes) {
|
|
645
|
+
const encoder = new TextEncoder;
|
|
646
|
+
const bytes = encoder.encode(output);
|
|
647
|
+
if (bytes.length <= maxBytes) {
|
|
648
|
+
return { text: output, truncated: false };
|
|
649
|
+
}
|
|
650
|
+
const decoder = new TextDecoder("utf-8", { fatal: false });
|
|
651
|
+
const truncated = decoder.decode(bytes.slice(0, maxBytes));
|
|
652
|
+
return {
|
|
653
|
+
text: `${truncated}
|
|
654
|
+
|
|
655
|
+
--- OUTPUT TRUNCATED (${bytes.length} bytes, limit: ${maxBytes}) ---`,
|
|
656
|
+
truncated: true
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
function maskSecrets(text, secrets) {
|
|
660
|
+
let result = text;
|
|
661
|
+
for (const value of Object.values(secrets)) {
|
|
662
|
+
if (value.length > 0) {
|
|
663
|
+
result = result.replaceAll(value, "***");
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
return result;
|
|
667
|
+
}
|
|
668
|
+
function createTarBuffer(filePath, content) {
|
|
669
|
+
const data = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
|
|
670
|
+
const headerSize = 512;
|
|
671
|
+
const dataBlocks = Math.ceil(data.length / 512);
|
|
672
|
+
const totalSize = headerSize + dataBlocks * 512 + 1024;
|
|
673
|
+
const buf = Buffer.alloc(totalSize);
|
|
674
|
+
buf.write(filePath.replace(/^\//, ""), 0, 100, "utf-8");
|
|
675
|
+
buf.write("0000644\x00", 100, 8, "utf-8");
|
|
676
|
+
buf.write("0000000\x00", 108, 8, "utf-8");
|
|
677
|
+
buf.write("0000000\x00", 116, 8, "utf-8");
|
|
678
|
+
buf.write(`${data.length.toString(8).padStart(11, "0")}\x00`, 124, 12, "utf-8");
|
|
679
|
+
buf.write(`${Math.floor(Date.now() / 1000).toString(8).padStart(11, "0")}\x00`, 136, 12, "utf-8");
|
|
680
|
+
buf.write("0", 156, 1, "utf-8");
|
|
681
|
+
buf.write("ustar\x00", 257, 6, "utf-8");
|
|
682
|
+
buf.write("00", 263, 2, "utf-8");
|
|
683
|
+
buf.write(" ", 148, 8, "utf-8");
|
|
684
|
+
let checksum = 0;
|
|
685
|
+
for (let i = 0;i < headerSize; i++) {
|
|
686
|
+
checksum += buf[i];
|
|
687
|
+
}
|
|
688
|
+
buf.write(`${checksum.toString(8).padStart(6, "0")}\x00 `, 148, 8, "utf-8");
|
|
689
|
+
data.copy(buf, headerSize);
|
|
690
|
+
return buf;
|
|
691
|
+
}
|
|
692
|
+
function extractFromTar(tarBuffer, targetPath) {
|
|
693
|
+
const normalizedTarget = targetPath.replace(/^\//, "");
|
|
694
|
+
const basename = targetPath.split("/").pop() ?? targetPath;
|
|
695
|
+
let offset = 0;
|
|
696
|
+
while (offset < tarBuffer.length - 512) {
|
|
697
|
+
const nameEnd = tarBuffer.indexOf(0, offset);
|
|
698
|
+
const name = tarBuffer.subarray(offset, Math.min(nameEnd, offset + 100)).toString("utf-8");
|
|
699
|
+
if (name.length === 0) {
|
|
700
|
+
break;
|
|
701
|
+
}
|
|
702
|
+
const sizeStr = tarBuffer.subarray(offset + 124, offset + 136).toString("utf-8").trim();
|
|
703
|
+
const size = Number.parseInt(sizeStr, 8);
|
|
704
|
+
if (Number.isNaN(size)) {
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
const dataStart = offset + 512;
|
|
708
|
+
const dataBlocks = Math.ceil(size / 512);
|
|
709
|
+
if (name === normalizedTarget || name.endsWith(`/${normalizedTarget}`) || name === basename) {
|
|
710
|
+
return Buffer.from(tarBuffer.subarray(dataStart, dataStart + size));
|
|
711
|
+
}
|
|
712
|
+
offset = dataStart + dataBlocks * 512;
|
|
713
|
+
}
|
|
714
|
+
throw new Error(`File "${targetPath}" not found in tar archive`);
|
|
715
|
+
}
|
|
716
|
+
function validatePackageName(name) {
|
|
717
|
+
if (!/^[@a-zA-Z0-9_./\-=]+$/.test(name)) {
|
|
718
|
+
throw new Error(`Invalid package name: "${name}". Only alphanumeric, -, _, ., /, @, and = are allowed.`);
|
|
719
|
+
}
|
|
720
|
+
return name;
|
|
721
|
+
}
|
|
722
|
+
|
|
616
723
|
// src/engine/image-builder.ts
|
|
724
|
+
var exports_image_builder = {};
|
|
725
|
+
__export(exports_image_builder, {
|
|
726
|
+
normalizePackages: () => normalizePackages,
|
|
727
|
+
imageExists: () => imageExists,
|
|
728
|
+
getCustomImageTag: () => getCustomImageTag,
|
|
729
|
+
ensureImages: () => ensureImages,
|
|
730
|
+
buildCustomImages: () => buildCustomImages,
|
|
731
|
+
buildCustomImage: () => buildCustomImage,
|
|
732
|
+
buildBaseImages: () => buildBaseImages
|
|
733
|
+
});
|
|
617
734
|
import { createHash as createHash2 } from "node:crypto";
|
|
618
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
735
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
|
|
736
|
+
import { dirname, join as join3 } from "node:path";
|
|
619
737
|
function resolveDockerDir() {
|
|
620
|
-
const
|
|
621
|
-
if (existsSync3(
|
|
622
|
-
return
|
|
738
|
+
const fromExec = join3(dirname(process.execPath), "docker");
|
|
739
|
+
if (existsSync3(fromExec) && statSync2(fromExec).isDirectory()) {
|
|
740
|
+
return fromExec;
|
|
741
|
+
}
|
|
742
|
+
if (!import.meta.url.includes("$bunfs")) {
|
|
743
|
+
const fromBundled = new URL("./docker", import.meta.url).pathname;
|
|
744
|
+
if (existsSync3(fromBundled)) {
|
|
745
|
+
return fromBundled;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
if (!import.meta.url.includes("$bunfs")) {
|
|
749
|
+
const fromDev = new URL("../../docker", import.meta.url).pathname;
|
|
750
|
+
if (existsSync3(fromDev)) {
|
|
751
|
+
return fromDev;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
const fromCwd = join3(process.cwd(), "docker");
|
|
755
|
+
if (existsSync3(fromCwd)) {
|
|
756
|
+
return fromCwd;
|
|
623
757
|
}
|
|
624
758
|
return new URL("../../docker", import.meta.url).pathname;
|
|
625
759
|
}
|
|
760
|
+
function computeDockerDirHash() {
|
|
761
|
+
const hash = createHash2("sha256");
|
|
762
|
+
const files = [...DOCKER_BUILD_FILES].sort();
|
|
763
|
+
for (const file of files) {
|
|
764
|
+
const filePath = join3(DOCKERFILE_DIR, file);
|
|
765
|
+
if (existsSync3(filePath)) {
|
|
766
|
+
const content = readFileSync2(filePath);
|
|
767
|
+
hash.update(file);
|
|
768
|
+
hash.update(content);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
return hash.digest("hex");
|
|
772
|
+
}
|
|
626
773
|
function computeDepsHash(runtime, packages) {
|
|
627
774
|
const hash = createHash2("sha256");
|
|
628
775
|
hash.update(runtime);
|
|
@@ -640,11 +787,206 @@ function getCustomImageTag(runtime, packages) {
|
|
|
640
787
|
const shortHash = depsHash.slice(0, 12);
|
|
641
788
|
return `isol8:${runtime}-custom-${shortHash}`;
|
|
642
789
|
}
|
|
643
|
-
|
|
790
|
+
async function getImageLabels(docker, imageName) {
|
|
791
|
+
try {
|
|
792
|
+
const image = docker.getImage(imageName);
|
|
793
|
+
const inspect = await image.inspect();
|
|
794
|
+
return inspect.Config?.Labels ?? {};
|
|
795
|
+
} catch {
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
async function removeImage(docker, imageId) {
|
|
800
|
+
try {
|
|
801
|
+
const image = docker.getImage(imageId);
|
|
802
|
+
await image.remove();
|
|
803
|
+
logger.debug(`[ImageBuilder] Removed old image: ${imageId.slice(0, 12)}`);
|
|
804
|
+
} catch (err) {
|
|
805
|
+
logger.debug(`[ImageBuilder] Could not remove image ${imageId.slice(0, 12)}: ${err}`);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
async function buildBaseImages(docker, onProgress, force = false, onlyRuntimes) {
|
|
809
|
+
const allRuntimes = RuntimeRegistry.list();
|
|
810
|
+
const runtimes = onlyRuntimes ? allRuntimes.filter((r) => onlyRuntimes.includes(r.name)) : allRuntimes;
|
|
811
|
+
const dockerHash = computeDockerDirHash();
|
|
812
|
+
logger.debug(`[ImageBuilder] Docker directory hash: ${dockerHash.slice(0, 16)}...`);
|
|
813
|
+
for (const adapter of runtimes) {
|
|
814
|
+
const target = adapter.name;
|
|
815
|
+
const imageName = adapter.image;
|
|
816
|
+
if (!force) {
|
|
817
|
+
const labels = await getImageLabels(docker, imageName);
|
|
818
|
+
if (labels && labels[LABELS.dockerHash] === dockerHash) {
|
|
819
|
+
logger.debug(`[ImageBuilder] Base image ${target} is up to date, skipping build`);
|
|
820
|
+
onProgress?.({ runtime: target, status: "done", message: "Up to date" });
|
|
821
|
+
continue;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
let oldImageId = null;
|
|
825
|
+
try {
|
|
826
|
+
const oldImage = await docker.getImage(imageName).inspect();
|
|
827
|
+
oldImageId = oldImage.Id;
|
|
828
|
+
logger.debug(`[ImageBuilder] Existing image ${target} ID: ${oldImageId.slice(0, 12)}`);
|
|
829
|
+
} catch {
|
|
830
|
+
logger.debug(`[ImageBuilder] No existing image for ${target}`);
|
|
831
|
+
}
|
|
832
|
+
onProgress?.({ runtime: target, status: "building" });
|
|
833
|
+
try {
|
|
834
|
+
const stream = await docker.buildImage({ context: DOCKERFILE_DIR, src: DOCKER_BUILD_FILES }, {
|
|
835
|
+
t: imageName,
|
|
836
|
+
target,
|
|
837
|
+
dockerfile: "Dockerfile",
|
|
838
|
+
labels: {
|
|
839
|
+
[LABELS.dockerHash]: dockerHash
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
await new Promise((resolve2, reject) => {
|
|
843
|
+
docker.modem.followProgress(stream, (err) => {
|
|
844
|
+
if (err) {
|
|
845
|
+
reject(err);
|
|
846
|
+
} else {
|
|
847
|
+
resolve2();
|
|
848
|
+
}
|
|
849
|
+
});
|
|
850
|
+
});
|
|
851
|
+
if (oldImageId) {
|
|
852
|
+
await removeImage(docker, oldImageId);
|
|
853
|
+
}
|
|
854
|
+
onProgress?.({ runtime: target, status: "done" });
|
|
855
|
+
} catch (err) {
|
|
856
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
857
|
+
onProgress?.({ runtime: target, status: "error", message });
|
|
858
|
+
throw new Error(`Failed to build image for ${target}: ${message}`);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
async function buildCustomImages(docker, config, onProgress, force = false) {
|
|
863
|
+
const deps = config.dependencies;
|
|
864
|
+
const python = deps.python ? normalizePackages(deps.python) : [];
|
|
865
|
+
const node = deps.node ? normalizePackages(deps.node) : [];
|
|
866
|
+
const bun = deps.bun ? normalizePackages(deps.bun) : [];
|
|
867
|
+
const deno = deps.deno ? normalizePackages(deps.deno) : [];
|
|
868
|
+
const bash = deps.bash ? normalizePackages(deps.bash) : [];
|
|
869
|
+
if (python.length) {
|
|
870
|
+
await buildCustomImage(docker, "python", python, onProgress, force);
|
|
871
|
+
}
|
|
872
|
+
if (node.length) {
|
|
873
|
+
await buildCustomImage(docker, "node", node, onProgress, force);
|
|
874
|
+
}
|
|
875
|
+
if (bun.length) {
|
|
876
|
+
await buildCustomImage(docker, "bun", bun, onProgress, force);
|
|
877
|
+
}
|
|
878
|
+
if (deno.length) {
|
|
879
|
+
await buildCustomImage(docker, "deno", deno, onProgress, force);
|
|
880
|
+
}
|
|
881
|
+
if (bash.length) {
|
|
882
|
+
await buildCustomImage(docker, "bash", bash, onProgress, force);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
async function buildCustomImage(docker, runtime, packages, onProgress, force = false) {
|
|
886
|
+
const normalizedPackages = normalizePackages(packages);
|
|
887
|
+
const tag = getCustomImageTag(runtime, normalizedPackages);
|
|
888
|
+
const depsHash = computeDepsHash(runtime, normalizedPackages);
|
|
889
|
+
logger.debug(`[ImageBuilder] ${runtime} custom deps hash: ${depsHash.slice(0, 16)}...`);
|
|
890
|
+
if (!force) {
|
|
891
|
+
const labels = await getImageLabels(docker, tag);
|
|
892
|
+
if (labels && labels[LABELS.depsHash] === depsHash) {
|
|
893
|
+
logger.debug(`[ImageBuilder] Custom image ${runtime} is up to date, skipping build`);
|
|
894
|
+
onProgress?.({ runtime, status: "done", message: "Up to date" });
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
let oldImageId = null;
|
|
899
|
+
try {
|
|
900
|
+
const oldImage = await docker.getImage(tag).inspect();
|
|
901
|
+
oldImageId = oldImage.Id;
|
|
902
|
+
logger.debug(`[ImageBuilder] Existing custom image ${runtime} ID: ${oldImageId.slice(0, 12)}`);
|
|
903
|
+
} catch {
|
|
904
|
+
logger.debug(`[ImageBuilder] No existing custom image for ${runtime}`);
|
|
905
|
+
}
|
|
906
|
+
onProgress?.({
|
|
907
|
+
runtime,
|
|
908
|
+
status: "building",
|
|
909
|
+
message: `Custom: ${normalizedPackages.join(", ")}`
|
|
910
|
+
});
|
|
911
|
+
let installCmd;
|
|
912
|
+
switch (runtime) {
|
|
913
|
+
case "python":
|
|
914
|
+
installCmd = `RUN pip install --no-cache-dir ${normalizedPackages.join(" ")}`;
|
|
915
|
+
break;
|
|
916
|
+
case "node":
|
|
917
|
+
installCmd = `RUN npm install -g ${normalizedPackages.join(" ")}`;
|
|
918
|
+
break;
|
|
919
|
+
case "bun":
|
|
920
|
+
installCmd = `RUN bun install -g ${normalizedPackages.join(" ")}`;
|
|
921
|
+
break;
|
|
922
|
+
case "deno":
|
|
923
|
+
installCmd = normalizedPackages.map((p) => `RUN deno cache ${p}`).join(`
|
|
924
|
+
`);
|
|
925
|
+
break;
|
|
926
|
+
case "bash":
|
|
927
|
+
installCmd = `RUN apk add --no-cache ${normalizedPackages.join(" ")}`;
|
|
928
|
+
break;
|
|
929
|
+
default:
|
|
930
|
+
throw new Error(`Unknown runtime: ${runtime}`);
|
|
931
|
+
}
|
|
932
|
+
const dockerfileContent = `FROM isol8:${runtime}
|
|
933
|
+
${installCmd}
|
|
934
|
+
`;
|
|
935
|
+
const { createTarBuffer: createTarBuffer2, validatePackageName: validatePackageName2 } = await Promise.resolve().then(() => exports_utils);
|
|
936
|
+
const { Readable } = await import("node:stream");
|
|
937
|
+
normalizedPackages.forEach(validatePackageName2);
|
|
938
|
+
const tarBuffer = createTarBuffer2("Dockerfile", dockerfileContent);
|
|
939
|
+
const stream = await docker.buildImage(Readable.from(tarBuffer), {
|
|
940
|
+
t: tag,
|
|
941
|
+
dockerfile: "Dockerfile",
|
|
942
|
+
labels: {
|
|
943
|
+
[LABELS.depsHash]: depsHash
|
|
944
|
+
}
|
|
945
|
+
});
|
|
946
|
+
await new Promise((resolve2, reject) => {
|
|
947
|
+
docker.modem.followProgress(stream, (err) => {
|
|
948
|
+
if (err) {
|
|
949
|
+
reject(err);
|
|
950
|
+
} else {
|
|
951
|
+
resolve2();
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
});
|
|
955
|
+
if (oldImageId) {
|
|
956
|
+
await removeImage(docker, oldImageId);
|
|
957
|
+
}
|
|
958
|
+
onProgress?.({ runtime, status: "done" });
|
|
959
|
+
}
|
|
960
|
+
async function imageExists(docker, imageName) {
|
|
961
|
+
try {
|
|
962
|
+
await docker.getImage(imageName).inspect();
|
|
963
|
+
return true;
|
|
964
|
+
} catch {
|
|
965
|
+
return false;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
async function ensureImages(docker, onProgress) {
|
|
969
|
+
const runtimes = RuntimeRegistry.list();
|
|
970
|
+
const missing = [];
|
|
971
|
+
for (const adapter of runtimes) {
|
|
972
|
+
if (!await imageExists(docker, adapter.image)) {
|
|
973
|
+
missing.push(adapter.name);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
if (missing.length > 0) {
|
|
977
|
+
await buildBaseImages(docker, onProgress, false, missing);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
var DOCKERFILE_DIR, LABELS, DOCKER_BUILD_FILES;
|
|
644
981
|
var init_image_builder = __esm(() => {
|
|
645
982
|
init_runtime();
|
|
646
983
|
init_logger();
|
|
647
984
|
DOCKERFILE_DIR = resolveDockerDir();
|
|
985
|
+
LABELS = {
|
|
986
|
+
dockerHash: "org.isol8.build.hash",
|
|
987
|
+
depsHash: "org.isol8.deps.hash"
|
|
988
|
+
};
|
|
989
|
+
DOCKER_BUILD_FILES = ["Dockerfile", "proxy.sh", "proxy-handler.sh"];
|
|
648
990
|
});
|
|
649
991
|
|
|
650
992
|
// src/engine/pool.ts
|
|
@@ -926,96 +1268,6 @@ function calculateResourceDelta(before, after) {
|
|
|
926
1268
|
};
|
|
927
1269
|
}
|
|
928
1270
|
|
|
929
|
-
// src/engine/utils.ts
|
|
930
|
-
function parseMemoryLimit(limit) {
|
|
931
|
-
const match = limit.match(/^(\d+(?:\.\d+)?)\s*([kmgt]?)b?$/i);
|
|
932
|
-
if (!match) {
|
|
933
|
-
throw new Error(`Invalid memory limit format: "${limit}". Use e.g. "512m", "1g".`);
|
|
934
|
-
}
|
|
935
|
-
const value = Number.parseFloat(match[1]);
|
|
936
|
-
const unit = (match[2] || "b").toLowerCase();
|
|
937
|
-
const multipliers = {
|
|
938
|
-
b: 1,
|
|
939
|
-
k: 1024,
|
|
940
|
-
m: 1024 ** 2,
|
|
941
|
-
g: 1024 ** 3,
|
|
942
|
-
t: 1024 ** 4
|
|
943
|
-
};
|
|
944
|
-
return Math.floor(value * (multipliers[unit] ?? 1));
|
|
945
|
-
}
|
|
946
|
-
function truncateOutput(output, maxBytes) {
|
|
947
|
-
const encoder = new TextEncoder;
|
|
948
|
-
const bytes = encoder.encode(output);
|
|
949
|
-
if (bytes.length <= maxBytes) {
|
|
950
|
-
return { text: output, truncated: false };
|
|
951
|
-
}
|
|
952
|
-
const decoder = new TextDecoder("utf-8", { fatal: false });
|
|
953
|
-
const truncated = decoder.decode(bytes.slice(0, maxBytes));
|
|
954
|
-
return {
|
|
955
|
-
text: `${truncated}
|
|
956
|
-
|
|
957
|
-
--- OUTPUT TRUNCATED (${bytes.length} bytes, limit: ${maxBytes}) ---`,
|
|
958
|
-
truncated: true
|
|
959
|
-
};
|
|
960
|
-
}
|
|
961
|
-
function maskSecrets(text, secrets) {
|
|
962
|
-
let result = text;
|
|
963
|
-
for (const value of Object.values(secrets)) {
|
|
964
|
-
if (value.length > 0) {
|
|
965
|
-
result = result.replaceAll(value, "***");
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
return result;
|
|
969
|
-
}
|
|
970
|
-
function createTarBuffer(filePath, content) {
|
|
971
|
-
const data = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
|
|
972
|
-
const headerSize = 512;
|
|
973
|
-
const dataBlocks = Math.ceil(data.length / 512);
|
|
974
|
-
const totalSize = headerSize + dataBlocks * 512 + 1024;
|
|
975
|
-
const buf = Buffer.alloc(totalSize);
|
|
976
|
-
buf.write(filePath.replace(/^\//, ""), 0, 100, "utf-8");
|
|
977
|
-
buf.write("0000644\x00", 100, 8, "utf-8");
|
|
978
|
-
buf.write("0000000\x00", 108, 8, "utf-8");
|
|
979
|
-
buf.write("0000000\x00", 116, 8, "utf-8");
|
|
980
|
-
buf.write(`${data.length.toString(8).padStart(11, "0")}\x00`, 124, 12, "utf-8");
|
|
981
|
-
buf.write(`${Math.floor(Date.now() / 1000).toString(8).padStart(11, "0")}\x00`, 136, 12, "utf-8");
|
|
982
|
-
buf.write("0", 156, 1, "utf-8");
|
|
983
|
-
buf.write("ustar\x00", 257, 6, "utf-8");
|
|
984
|
-
buf.write("00", 263, 2, "utf-8");
|
|
985
|
-
buf.write(" ", 148, 8, "utf-8");
|
|
986
|
-
let checksum = 0;
|
|
987
|
-
for (let i = 0;i < headerSize; i++) {
|
|
988
|
-
checksum += buf[i];
|
|
989
|
-
}
|
|
990
|
-
buf.write(`${checksum.toString(8).padStart(6, "0")}\x00 `, 148, 8, "utf-8");
|
|
991
|
-
data.copy(buf, headerSize);
|
|
992
|
-
return buf;
|
|
993
|
-
}
|
|
994
|
-
function extractFromTar(tarBuffer, targetPath) {
|
|
995
|
-
const normalizedTarget = targetPath.replace(/^\//, "");
|
|
996
|
-
const basename = targetPath.split("/").pop() ?? targetPath;
|
|
997
|
-
let offset = 0;
|
|
998
|
-
while (offset < tarBuffer.length - 512) {
|
|
999
|
-
const nameEnd = tarBuffer.indexOf(0, offset);
|
|
1000
|
-
const name = tarBuffer.subarray(offset, Math.min(nameEnd, offset + 100)).toString("utf-8");
|
|
1001
|
-
if (name.length === 0) {
|
|
1002
|
-
break;
|
|
1003
|
-
}
|
|
1004
|
-
const sizeStr = tarBuffer.subarray(offset + 124, offset + 136).toString("utf-8").trim();
|
|
1005
|
-
const size = Number.parseInt(sizeStr, 8);
|
|
1006
|
-
if (Number.isNaN(size)) {
|
|
1007
|
-
break;
|
|
1008
|
-
}
|
|
1009
|
-
const dataStart = offset + 512;
|
|
1010
|
-
const dataBlocks = Math.ceil(size / 512);
|
|
1011
|
-
if (name === normalizedTarget || name.endsWith(`/${normalizedTarget}`) || name === basename) {
|
|
1012
|
-
return Buffer.from(tarBuffer.subarray(dataStart, dataStart + size));
|
|
1013
|
-
}
|
|
1014
|
-
offset = dataStart + dataBlocks * 512;
|
|
1015
|
-
}
|
|
1016
|
-
throw new Error(`File "${targetPath}" not found in tar archive`);
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
1271
|
// src/engine/docker.ts
|
|
1020
1272
|
var exports_docker = {};
|
|
1021
1273
|
__export(exports_docker, {
|
|
@@ -1624,6 +1876,25 @@ class DockerIsol8 {
|
|
|
1624
1876
|
resolvedImage = legacyCustomTag;
|
|
1625
1877
|
} catch {}
|
|
1626
1878
|
}
|
|
1879
|
+
try {
|
|
1880
|
+
await this.docker.getImage(resolvedImage).inspect();
|
|
1881
|
+
} catch {
|
|
1882
|
+
logger.debug(`[ImageBuilder] Image ${resolvedImage} not found. Building...`);
|
|
1883
|
+
const { buildBaseImages: buildBaseImages2, buildCustomImage: buildCustomImage2 } = await Promise.resolve().then(() => (init_image_builder(), exports_image_builder));
|
|
1884
|
+
if (resolvedImage !== adapter.image && normalizedDeps.length > 0) {
|
|
1885
|
+
try {
|
|
1886
|
+
await this.docker.getImage(adapter.image).inspect();
|
|
1887
|
+
} catch {
|
|
1888
|
+
logger.debug(`[ImageBuilder] Base image ${adapter.image} missing. Building...`);
|
|
1889
|
+
await buildBaseImages2(this.docker, undefined, false, [adapter.name]);
|
|
1890
|
+
}
|
|
1891
|
+
logger.debug(`[ImageBuilder] Building custom image for ${adapter.name}...`);
|
|
1892
|
+
await buildCustomImage2(this.docker, adapter.name, normalizedDeps);
|
|
1893
|
+
} else {
|
|
1894
|
+
logger.debug(`[ImageBuilder] Building base image for ${adapter.name}...`);
|
|
1895
|
+
await buildBaseImages2(this.docker, undefined, false, [adapter.name]);
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1627
1898
|
this.imageCache.set(cacheKey, resolvedImage);
|
|
1628
1899
|
return resolvedImage;
|
|
1629
1900
|
}
|
|
@@ -2445,7 +2716,7 @@ init_logger();
|
|
|
2445
2716
|
// package.json
|
|
2446
2717
|
var package_default = {
|
|
2447
2718
|
name: "isol8",
|
|
2448
|
-
version: "0.
|
|
2719
|
+
version: "0.12.1",
|
|
2449
2720
|
description: "Secure code execution engine for AI agents",
|
|
2450
2721
|
author: "Illusion47586",
|
|
2451
2722
|
license: "MIT",
|
|
@@ -2878,4 +3149,4 @@ export {
|
|
|
2878
3149
|
BunAdapter
|
|
2879
3150
|
};
|
|
2880
3151
|
|
|
2881
|
-
//# debugId=
|
|
3152
|
+
//# debugId=134AC8BB795B367A64756E2164756E21
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../../src/engine/docker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,MAAM,MAAM,WAAW,CAAC;AAG/B,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EAEf,WAAW,EAEX,YAAY,EAKZ,YAAY,EACZ,WAAW,EACZ,MAAM,UAAU,CAAC;AAuWlB,2HAA2H;AAC3H,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,WAAY,YAAW,WAAW;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAsB;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4C;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IAEpD,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;YAE1C,uBAAuB;IA6BrC;;;OAGG;gBACS,OAAO,GAAE,kBAAuB,EAAE,aAAa,SAAK;IA4ChE;;;;;OAKG;IACG,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCtD,kFAAkF;IAC5E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAgB9D;;OAEG;YACW,WAAW;IAoDzB;;OAEG;YACW,qBAAqB;IA8CnC;;OAEG;YACW,kBAAkB;IA+DhC;;;;;;;OAOG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpE;;;;;;OAMG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmB5C,6GAA6G;IAC7G,IAAI,WAAW,IAAI,MAAM,GAAG,IAAI,CAE/B;IAED;;;OAGG;IACI,aAAa,CAAC,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAAC,WAAW,CAAC;YAuFzD,YAAY;
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../../src/engine/docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -43,7 +43,7 @@ type ProgressCallback = (progress: BuildProgress) => void;
|
|
|
43
43
|
* @param onProgress - Optional callback for build progress updates.
|
|
44
44
|
* @param force - If true, always rebuild even if image is up to date.
|
|
45
45
|
*/
|
|
46
|
-
export declare function buildBaseImages(docker: Docker, onProgress?: ProgressCallback, force?: boolean): Promise<void>;
|
|
46
|
+
export declare function buildBaseImages(docker: Docker, onProgress?: ProgressCallback, force?: boolean, onlyRuntimes?: string[]): Promise<void>;
|
|
47
47
|
/**
|
|
48
48
|
* Builds custom images with user-specified dependencies layered on top of
|
|
49
49
|
* the base images. Reads package lists from the config's `dependencies` field.
|
|
@@ -58,6 +58,7 @@ export declare function buildBaseImages(docker: Docker, onProgress?: ProgressCal
|
|
|
58
58
|
* @param force - If true, always rebuild even if image is up to date.
|
|
59
59
|
*/
|
|
60
60
|
export declare function buildCustomImages(docker: Docker, config: Isol8Config, onProgress?: ProgressCallback, force?: boolean): Promise<void>;
|
|
61
|
+
export declare function buildCustomImage(docker: Docker, runtime: import("../types").Runtime | string, packages: string[], onProgress?: ProgressCallback, force?: boolean): Promise<void>;
|
|
61
62
|
/**
|
|
62
63
|
* Checks if an image exists locally.
|
|
63
64
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-builder.d.ts","sourceRoot":"","sources":["../../../src/engine/image-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,MAAM,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"image-builder.d.ts","sourceRoot":"","sources":["../../../src/engine/image-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,MAAM,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AA6F5C;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAK7E;AAkCD,mDAAmD;AACnD,UAAU,aAAa;IACrB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;IACtC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,KAAK,gBAAgB,GAAG,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;AAE1D;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,gBAAgB,EAC7B,KAAK,UAAQ,EACb,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAuEf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,EACnB,UAAU,CAAC,EAAE,gBAAgB,EAC7B,KAAK,UAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,UAAU,EAAE,OAAO,GAAG,MAAM,EAC5C,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,CAAC,EAAE,gBAAgB,EAC7B,KAAK,UAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CA2Ff;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOrF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAa/F"}
|