@moinulmoin/eden 0.5.0 → 0.7.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/NOTICE +0 -9
- package/README.md +14 -10
- package/dist/eve-control-plane.d.ts +21 -18
- package/dist/eve-control-plane.js +271 -219
- package/dist/eve-packaging.d.ts +79 -12
- package/dist/eve-packaging.js +342 -60
- package/dist/eve-runtime-config.d.ts +7 -2
- package/dist/eve-runtime-config.js +7 -2
- package/dist/eve-runtime-image.d.ts +12 -9
- package/dist/eve-runtime-image.js +140 -62
- package/dist/eve.d.ts +1 -2
- package/dist/eve.js +1 -18
- package/dist/index.d.ts +5 -8
- package/dist/index.js +2 -10
- package/package.json +3 -3
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import { type EveNodeImage, type EvePackagingCheck, type EvePackagingCode, type EveProjectBuildCandidate, type EveProjectOutput } from "./eve-packaging.js";
|
|
2
|
-
import type
|
|
3
|
-
declare const START_COMMAND: readonly ["./node_modules/.bin/eve", "start", "--host", "0.0.0.0", "--port", "8080"];
|
|
2
|
+
import { EVE_HOST_ENVIRONMENT as HOST_ENVIRONMENT, EVE_START_COMMAND as START_COMMAND, type EveRuntimeInjection } from "./eve-runtime-config.js";
|
|
4
3
|
declare const HEALTH_PATH: "/eve/v1/health";
|
|
5
|
-
declare const HOST_ENVIRONMENT: {
|
|
6
|
-
readonly HOST: "0.0.0.0";
|
|
7
|
-
readonly NITRO_HOST: "0.0.0.0";
|
|
8
|
-
readonly PORT: "8080";
|
|
9
|
-
readonly NITRO_PORT: "8080";
|
|
10
|
-
readonly NODE_ENV: "production";
|
|
11
|
-
};
|
|
12
4
|
export interface EveHostRequirements {
|
|
13
5
|
readonly architecture: string;
|
|
14
6
|
readonly world: "supported" | "unsupported" | "unknown";
|
|
@@ -39,6 +31,17 @@ export interface EveRuntimeClosure {
|
|
|
39
31
|
readonly nativeModules: readonly EveRuntimeNativeModule[];
|
|
40
32
|
readonly eveStartClosureRetained: true;
|
|
41
33
|
readonly builderOnlyMaterialExcluded: true;
|
|
34
|
+
/**
|
|
35
|
+
* The prepared sandbox-template tree shipped at
|
|
36
|
+
* `/workspace/.eve/sandbox-cache`. Present only when this Eve build
|
|
37
|
+
* prepared a sandbox template; without it Eve's sandbox tools fail on the
|
|
38
|
+
* deployed agent.
|
|
39
|
+
*/
|
|
40
|
+
readonly sandboxTemplate?: {
|
|
41
|
+
readonly root: "/workspace/.eve/sandbox-cache";
|
|
42
|
+
readonly digest: string;
|
|
43
|
+
readonly files: readonly EveRuntimeClosureFile[];
|
|
44
|
+
};
|
|
42
45
|
}
|
|
43
46
|
export interface EveRuntimeImage extends EveRuntimeImageMetadata {
|
|
44
47
|
readonly runtimeClosure: EveRuntimeClosure;
|
|
@@ -1,22 +1,12 @@
|
|
|
1
|
-
import { createHash, } from "node:crypto";
|
|
2
1
|
import { execFile, } from "node:child_process";
|
|
3
2
|
import { cp, lstat, mkdir, readFile, readlink, readdir, realpath, rm, symlink, writeFile, } from "node:fs/promises";
|
|
4
3
|
import { dirname, join, relative, resolve, } from "node:path";
|
|
5
4
|
import { promisify, } from "node:util";
|
|
6
|
-
import { EvePackagingError, eveSnapshotSourceEntries, } from "./eve-packaging.js";
|
|
5
|
+
import { EvePackagingError, EVE_SANDBOX_CACHE_ROOT, eveSnapshotSourceEntries, imageReference as packagingImageReference, IMAGE_ID_PATTERN, isWithin, jsonBytes, safeError as errorRecord, safeRelativePath, sha256, } from "./eve-packaging.js";
|
|
6
|
+
import { EVE_HOST_ENVIRONMENT as HOST_ENVIRONMENT, EVE_START_COMMAND as START_COMMAND, } from "./eve-runtime-config.js";
|
|
7
7
|
const execFileAsync = promisify(execFile);
|
|
8
|
-
const START_COMMAND = [
|
|
9
|
-
"./node_modules/.bin/eve",
|
|
10
|
-
"start",
|
|
11
|
-
"--host",
|
|
12
|
-
"0.0.0.0",
|
|
13
|
-
"--port",
|
|
14
|
-
"8080",
|
|
15
|
-
];
|
|
16
8
|
const HEALTH_PATH = "/eve/v1/health";
|
|
17
9
|
const INTERNAL_PORT = 8080;
|
|
18
|
-
const IMAGE_ID_PATTERN = /^sha256:[0-9a-f]{64}$/u;
|
|
19
|
-
const NODE_IMAGE_PATTERN = /^node:24\.17\.0(?:-[a-z0-9][a-z0-9._-]*)?$/u;
|
|
20
10
|
const FORBIDDEN_RUNTIME_NAMES = new Set([
|
|
21
11
|
".env",
|
|
22
12
|
".env.local",
|
|
@@ -29,26 +19,6 @@ const FORBIDDEN_RUNTIME_NAMES = new Set([
|
|
|
29
19
|
"credentials.json",
|
|
30
20
|
"service-account.json",
|
|
31
21
|
]);
|
|
32
|
-
const HOST_ENVIRONMENT = {
|
|
33
|
-
HOST: "0.0.0.0",
|
|
34
|
-
NITRO_HOST: "0.0.0.0",
|
|
35
|
-
PORT: "8080",
|
|
36
|
-
NITRO_PORT: "8080",
|
|
37
|
-
NODE_ENV: "production",
|
|
38
|
-
};
|
|
39
|
-
function sha256(value) {
|
|
40
|
-
return createHash("sha256").update(value).digest("hex");
|
|
41
|
-
}
|
|
42
|
-
function jsonBytes(value) {
|
|
43
|
-
return Buffer.from(`${JSON.stringify(value)}\n`, "utf8");
|
|
44
|
-
}
|
|
45
|
-
function isWithin(root, candidate) {
|
|
46
|
-
const normalizedRoot = root.endsWith("/") ? root.slice(0, -1) : root;
|
|
47
|
-
return candidate === normalizedRoot || candidate.startsWith(`${normalizedRoot}/`);
|
|
48
|
-
}
|
|
49
|
-
function safeRelativePath(root, candidate) {
|
|
50
|
-
return relative(root, candidate).split("\\").join("/");
|
|
51
|
-
}
|
|
52
22
|
async function assertFreshOwnedFilePath(path, root, subject) {
|
|
53
23
|
const canonicalRoot = await realpath(root).catch(() => undefined);
|
|
54
24
|
const canonicalParent = await realpath(dirname(path)).catch(() => undefined);
|
|
@@ -77,16 +47,7 @@ async function verifyOwnedFilePath(path, root, expectedParent, subject) {
|
|
|
77
47
|
}
|
|
78
48
|
}
|
|
79
49
|
function imageReference(nodeImage) {
|
|
80
|
-
|
|
81
|
-
!IMAGE_ID_PATTERN.test(nodeImage.digest)) {
|
|
82
|
-
throw new EvePackagingError({
|
|
83
|
-
code: "DOCKER_PLATFORM_BLOCKED",
|
|
84
|
-
subject: "node-24-image",
|
|
85
|
-
reason: "The runtime image requires an immutable Linux/amd64 Node 24 image.",
|
|
86
|
-
remediation: "Supply the verified Node 24 image reference and sha256 digest.",
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
return `${nodeImage.reference}@${nodeImage.digest}`;
|
|
50
|
+
return packagingImageReference(nodeImage, "The runtime image requires an immutable Linux/amd64 Node 24 image.", "Supply the verified Node 24 image reference and sha256 digest.");
|
|
90
51
|
}
|
|
91
52
|
function packagingError(code, subject, reason, remediation) {
|
|
92
53
|
return new EvePackagingError({
|
|
@@ -331,6 +292,34 @@ async function validateCandidateClosure(candidate) {
|
|
|
331
292
|
captureRuntimeTree(outputRoot, snapshotRoot, "output"),
|
|
332
293
|
captureRuntimeTree(dependenciesRoot, snapshotRoot, "dependencies"),
|
|
333
294
|
]);
|
|
295
|
+
const sandboxCacheRoot = join(snapshotRoot, EVE_SANDBOX_CACHE_ROOT);
|
|
296
|
+
const sandboxCacheDetails = await lstat(sandboxCacheRoot).catch(() => undefined);
|
|
297
|
+
let sandbox;
|
|
298
|
+
if (candidate.sandboxCache?.present === true) {
|
|
299
|
+
if (sandboxCacheDetails === undefined ||
|
|
300
|
+
!sandboxCacheDetails.isDirectory() ||
|
|
301
|
+
sandboxCacheDetails.isSymbolicLink()) {
|
|
302
|
+
throw packagingError("RUNTIME_CLOSURE_INCOMPLETE", EVE_SANDBOX_CACHE_ROOT, "The candidate records a prepared sandbox template but its tree is missing or not a regular directory.", "Regenerate the candidate so the isolated builder extracts .eve/sandbox-cache into the immutable snapshot.");
|
|
303
|
+
}
|
|
304
|
+
const capturedSandbox = await captureRuntimeTree(sandboxCacheRoot, snapshotRoot, "sandbox-template");
|
|
305
|
+
const sandboxEvidence = capturedSandbox.files.map((file) => ({
|
|
306
|
+
relativePath: file.path,
|
|
307
|
+
sha256: file.sha256,
|
|
308
|
+
byteLength: file.byteLength,
|
|
309
|
+
}));
|
|
310
|
+
const sandboxTotalBytes = capturedSandbox.files
|
|
311
|
+
.filter((file) => !file.symbolicLink)
|
|
312
|
+
.reduce((sum, file) => sum + file.byteLength, 0);
|
|
313
|
+
if (capturedSandbox.files.length !== candidate.sandboxCache.fileCount ||
|
|
314
|
+
sandboxTotalBytes !== candidate.sandboxCache.totalBytes ||
|
|
315
|
+
sha256(jsonBytes(sandboxEvidence)) !== candidate.sandboxCache.outputDigest) {
|
|
316
|
+
throw packagingError("SOURCE_RACE", EVE_SANDBOX_CACHE_ROOT, "The prepared sandbox template no longer matches the immutable candidate evidence.", "Discard the mixed-generation runtime candidate and rebuild from a quiescent snapshot.");
|
|
317
|
+
}
|
|
318
|
+
sandbox = { digest: capturedSandbox.digest, files: capturedSandbox.files };
|
|
319
|
+
}
|
|
320
|
+
else if (sandboxCacheDetails !== undefined) {
|
|
321
|
+
throw packagingError("SOURCE_RACE", EVE_SANDBOX_CACHE_ROOT, "The candidate records no prepared sandbox template but the immutable snapshot contains one.", "Discard the mixed-generation runtime candidate and rebuild from a quiescent snapshot.");
|
|
322
|
+
}
|
|
334
323
|
const entrypointBytes = await readRegularFile(entrypoint, snapshotRoot);
|
|
335
324
|
const candidateOutputDigest = sha256(jsonBytes(output.files.map((file) => ({
|
|
336
325
|
relativePath: file.path,
|
|
@@ -351,6 +340,7 @@ async function validateCandidateClosure(candidate) {
|
|
|
351
340
|
outputDigest: output.digest,
|
|
352
341
|
dependencyDigest: dependencies.digest,
|
|
353
342
|
})),
|
|
343
|
+
...(sandbox === undefined ? {} : { sandbox }),
|
|
354
344
|
};
|
|
355
345
|
}
|
|
356
346
|
export async function revalidateEveRuntimeCandidate(candidate) {
|
|
@@ -364,6 +354,15 @@ export async function revalidateEveRuntimeCandidate(candidate) {
|
|
|
364
354
|
nativeModules: closure.nativeModules,
|
|
365
355
|
eveStartClosureRetained: true,
|
|
366
356
|
builderOnlyMaterialExcluded: true,
|
|
357
|
+
...(closure.sandbox === undefined
|
|
358
|
+
? {}
|
|
359
|
+
: {
|
|
360
|
+
sandboxTemplate: {
|
|
361
|
+
root: "/workspace/.eve/sandbox-cache",
|
|
362
|
+
digest: closure.sandbox.digest,
|
|
363
|
+
files: closure.sandbox.files,
|
|
364
|
+
},
|
|
365
|
+
}),
|
|
367
366
|
};
|
|
368
367
|
}
|
|
369
368
|
/**
|
|
@@ -420,6 +419,12 @@ async function writeRuntimeContext(candidate, nodeImage, closure) {
|
|
|
420
419
|
try {
|
|
421
420
|
await cp(join(candidate.snapshotRoot, ".output"), join(runtimeContextPath, ".output"), { recursive: true });
|
|
422
421
|
await cp(join(candidate.snapshotRoot, "node_modules"), join(runtimeContextPath, "node_modules"), { recursive: true });
|
|
422
|
+
const sandboxCacheSource = join(candidate.snapshotRoot, EVE_SANDBOX_CACHE_ROOT);
|
|
423
|
+
const sandboxCacheContext = join(runtimeContextPath, EVE_SANDBOX_CACHE_ROOT);
|
|
424
|
+
if (closure.sandbox !== undefined) {
|
|
425
|
+
await cp(sandboxCacheSource, sandboxCacheContext, { recursive: true });
|
|
426
|
+
await rewriteContextLinks(sandboxCacheSource, sandboxCacheContext);
|
|
427
|
+
}
|
|
423
428
|
const sourceEntries = await eveSnapshotSourceEntries(candidate.snapshotRoot);
|
|
424
429
|
for (const entry of sourceEntries) {
|
|
425
430
|
await cp(join(candidate.snapshotRoot, entry), join(runtimeContextPath, entry), { recursive: true });
|
|
@@ -428,10 +433,20 @@ async function writeRuntimeContext(candidate, nodeImage, closure) {
|
|
|
428
433
|
await rewriteContextLinks(join(candidate.snapshotRoot, ".output"), join(runtimeContextPath, ".output"));
|
|
429
434
|
const copiedOutput = await captureRuntimeTree(join(runtimeContextPath, ".output"), runtimeContextPath, "output");
|
|
430
435
|
const copiedDependencies = await captureRuntimeTree(join(runtimeContextPath, "node_modules"), runtimeContextPath, "dependencies");
|
|
436
|
+
const copiedSandbox = closure.sandbox === undefined
|
|
437
|
+
? undefined
|
|
438
|
+
: await captureRuntimeTree(sandboxCacheContext, runtimeContextPath, "sandbox-template");
|
|
431
439
|
if (copiedOutput.digest !== closure.outputDigest ||
|
|
432
|
-
copiedDependencies.digest !== closure.dependencyDigest
|
|
440
|
+
copiedDependencies.digest !== closure.dependencyDigest ||
|
|
441
|
+
(closure.sandbox !== undefined && copiedSandbox?.digest !== closure.sandbox.digest)) {
|
|
433
442
|
throw packagingError("SOURCE_RACE", "runtime context", "The copied runtime context does not match the validated immutable closure.", "Discard the mixed-generation runtime context and rebuild from a quiescent candidate.");
|
|
434
443
|
}
|
|
444
|
+
const sandboxContextCopy = closure.sandbox === undefined
|
|
445
|
+
? ""
|
|
446
|
+
: `COPY ${JSON.stringify([EVE_SANDBOX_CACHE_ROOT, `/candidate/${EVE_SANDBOX_CACHE_ROOT}`])}\n`;
|
|
447
|
+
const sandboxImageCopy = closure.sandbox === undefined
|
|
448
|
+
? ""
|
|
449
|
+
: `COPY --from=candidate ${JSON.stringify([`/candidate/${EVE_SANDBOX_CACHE_ROOT}`, `/workspace/${EVE_SANDBOX_CACHE_ROOT}`])}\n`;
|
|
435
450
|
const sourceCopyLines = sourceEntries
|
|
436
451
|
.map((entry) => `COPY --from=candidate ${JSON.stringify([`/candidate/${entry}`, `/workspace/${entry}`])}`)
|
|
437
452
|
.join("\n");
|
|
@@ -440,7 +455,7 @@ FROM --platform=linux/amd64 ${imageReference(nodeImage)} AS candidate
|
|
|
440
455
|
WORKDIR /candidate
|
|
441
456
|
COPY .output /candidate/.output
|
|
442
457
|
COPY node_modules /candidate/node_modules
|
|
443
|
-
${sourceEntries.map((entry) => `COPY ${JSON.stringify([entry, `/candidate/${entry}`])}`).join("\n")}
|
|
458
|
+
${sandboxContextCopy}${sourceEntries.map((entry) => `COPY ${JSON.stringify([entry, `/candidate/${entry}`])}`).join("\n")}
|
|
444
459
|
|
|
445
460
|
FROM --platform=linux/amd64 ${imageReference(nodeImage)} AS runtime
|
|
446
461
|
WORKDIR /workspace
|
|
@@ -452,7 +467,7 @@ ENV HOST=0.0.0.0 \\
|
|
|
452
467
|
CBOR_NATIVE_ACCELERATION_DISABLED=true
|
|
453
468
|
COPY --from=candidate /candidate/.output /workspace/.output
|
|
454
469
|
COPY --from=candidate /candidate/node_modules /workspace/node_modules
|
|
455
|
-
${sourceCopyLines}
|
|
470
|
+
${sandboxImageCopy}${sourceCopyLines}
|
|
456
471
|
EXPOSE 8080
|
|
457
472
|
ENTRYPOINT ["./node_modules/.bin/eve", "start", "--host", "0.0.0.0", "--port", "8080"]
|
|
458
473
|
`;
|
|
@@ -572,6 +587,55 @@ function runtimeContainerEnvironment(request) {
|
|
|
572
587
|
: {}),
|
|
573
588
|
};
|
|
574
589
|
}
|
|
590
|
+
/**
|
|
591
|
+
* Absolute `/workspace` sandbox-template paths recorded by `eve build` in the
|
|
592
|
+
* compiled `sandbox-prepared-artifacts.json` manifest. The boot probe asserts
|
|
593
|
+
* each recorded template exists inside the built image. Paths outside the
|
|
594
|
+
* sandbox cache, or containing anything unsafe to interpolate into a single
|
|
595
|
+
*-quoted shell word, are skipped (packaging validation already bounded the
|
|
596
|
+
* tree; this is an end-to-end existence proof).
|
|
597
|
+
*/
|
|
598
|
+
async function eveSandboxTemplateBootPaths(candidate) {
|
|
599
|
+
if (candidate.sandboxCache?.present !== true)
|
|
600
|
+
return [];
|
|
601
|
+
const bootPrefix = `/workspace/${EVE_SANDBOX_CACHE_ROOT}/`;
|
|
602
|
+
const paths = new Set();
|
|
603
|
+
let parsed;
|
|
604
|
+
try {
|
|
605
|
+
parsed = JSON.parse(await readFile(join(candidate.snapshotRoot, ".output/.eve/compile/sandbox-prepared-artifacts.json"), "utf8"));
|
|
606
|
+
}
|
|
607
|
+
catch {
|
|
608
|
+
return [];
|
|
609
|
+
}
|
|
610
|
+
if (typeof parsed !== "object" || parsed === null || !("entries" in parsed)) {
|
|
611
|
+
return [];
|
|
612
|
+
}
|
|
613
|
+
const entries = parsed.entries;
|
|
614
|
+
if (!Array.isArray(entries))
|
|
615
|
+
return [];
|
|
616
|
+
for (const entry of entries) {
|
|
617
|
+
if (typeof entry !== "object" || entry === null || !("artifact" in entry)) {
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
const artifact = entry.artifact;
|
|
621
|
+
if (typeof artifact !== "object" ||
|
|
622
|
+
artifact === null ||
|
|
623
|
+
!("templateRootPath" in artifact) ||
|
|
624
|
+
typeof artifact.templateRootPath !== "string") {
|
|
625
|
+
continue;
|
|
626
|
+
}
|
|
627
|
+
const templateRootPath = artifact.templateRootPath;
|
|
628
|
+
if (!templateRootPath.startsWith(bootPrefix) ||
|
|
629
|
+
templateRootPath.slice(bootPrefix.length).length === 0 ||
|
|
630
|
+
templateRootPath.slice(bootPrefix.length).split("/").includes("..") ||
|
|
631
|
+
templateRootPath.includes("'") ||
|
|
632
|
+
templateRootPath.includes("\\")) {
|
|
633
|
+
continue;
|
|
634
|
+
}
|
|
635
|
+
paths.add(templateRootPath);
|
|
636
|
+
}
|
|
637
|
+
return [...paths].sort();
|
|
638
|
+
}
|
|
575
639
|
function validateHealthPort(port) {
|
|
576
640
|
if (!Number.isInteger(port) || port < 4310 || port > 4399) {
|
|
577
641
|
throw packagingError("DOCKER_PLATFORM_BLOCKED", "health port", "The local Eve health probe must use a task-owned host port in 4310-4399.", "Choose an unused task-owned host port between 4310 and 4399.");
|
|
@@ -822,14 +886,6 @@ async function pollEveHealth(port, timeoutMs, pollIntervalMs, fetchHealth) {
|
|
|
822
886
|
}
|
|
823
887
|
throw packagingError("EVE_HEALTH_FAILED", HEALTH_PATH, `The real Eve health route did not report ready before the bounded deadline (last status: ${lastStatus}).`, "Inspect the project-local eve start supervisor, Nitro child, sandbox prewarm, and Workflow World startup without replacing them with a synthetic listener.");
|
|
824
888
|
}
|
|
825
|
-
function errorRecord(error) {
|
|
826
|
-
return {
|
|
827
|
-
code: error.code,
|
|
828
|
-
subject: error.subject,
|
|
829
|
-
reason: error.message,
|
|
830
|
-
remediation: error.remediation,
|
|
831
|
-
};
|
|
832
|
-
}
|
|
833
889
|
function blockedResult(candidate, error, cleanup, writtenPaths) {
|
|
834
890
|
return {
|
|
835
891
|
schemaVersion: 1,
|
|
@@ -905,8 +961,12 @@ export async function buildEveRuntimeImage(request) {
|
|
|
905
961
|
]);
|
|
906
962
|
const postBuildOutput = await captureRuntimeTree(join(context.runtimeContextPath, ".output"), context.runtimeContextPath, "output");
|
|
907
963
|
const postBuildDependencies = await captureRuntimeTree(join(context.runtimeContextPath, "node_modules"), context.runtimeContextPath, "dependencies");
|
|
964
|
+
const postBuildSandbox = closure.sandbox === undefined
|
|
965
|
+
? undefined
|
|
966
|
+
: await captureRuntimeTree(join(context.runtimeContextPath, EVE_SANDBOX_CACHE_ROOT), context.runtimeContextPath, "sandbox-template");
|
|
908
967
|
if (postBuildOutput.digest !== closure.outputDigest ||
|
|
909
|
-
postBuildDependencies.digest !== closure.dependencyDigest
|
|
968
|
+
postBuildDependencies.digest !== closure.dependencyDigest ||
|
|
969
|
+
(closure.sandbox !== undefined && postBuildSandbox?.digest !== closure.sandbox.digest)) {
|
|
910
970
|
throw packagingError("SOURCE_RACE", "runtime context", "The runtime context changed while the immutable Linux/amd64 image was being built.", "Discard the mixed-generation runtime image and rebuild from a quiescent candidate.");
|
|
911
971
|
}
|
|
912
972
|
state.imageId = await recoverImageIdentity(state);
|
|
@@ -970,6 +1030,16 @@ export async function buildEveRuntimeImage(request) {
|
|
|
970
1030
|
"-ceu",
|
|
971
1031
|
"test -f /workspace/.output/server/index.mjs && test -x /workspace/node_modules/.bin/eve",
|
|
972
1032
|
]);
|
|
1033
|
+
const sandboxTemplatePaths = await eveSandboxTemplateBootPaths(request.candidate);
|
|
1034
|
+
if (sandboxTemplatePaths.length > 0) {
|
|
1035
|
+
await docker(state, [
|
|
1036
|
+
"exec",
|
|
1037
|
+
state.containerId,
|
|
1038
|
+
"sh",
|
|
1039
|
+
"-ceu",
|
|
1040
|
+
sandboxTemplatePaths.map((path) => `test -d '${path}'`).join(" && "),
|
|
1041
|
+
]);
|
|
1042
|
+
}
|
|
973
1043
|
await docker(state, [
|
|
974
1044
|
"exec",
|
|
975
1045
|
state.containerId,
|
|
@@ -1012,15 +1082,15 @@ export async function buildEveRuntimeImage(request) {
|
|
|
1012
1082
|
"-ceu",
|
|
1013
1083
|
"awk '$2 ~ /^00000000:1F90/ { found=1 } END { exit found ? 0 : 1 }' /proc/net/tcp /proc/net/tcp6",
|
|
1014
1084
|
]);
|
|
1015
|
-
await docker(state, [
|
|
1016
|
-
"exec",
|
|
1017
|
-
state.containerId,
|
|
1018
|
-
"sh",
|
|
1019
|
-
"-ceu",
|
|
1020
|
-
"test -z \"$(find /app -type f \\( -name '.env*' -o -name '.npmrc' -o -name '.pnpmrc' -o -name '*.pem' -o -name '*.key' -o -name 'credentials.json' -o -name 'service-account.json' \\) -print -quit)\"",
|
|
1021
|
-
]);
|
|
1022
1085
|
imageRetained = retainImage;
|
|
1023
1086
|
state.imageRetained = retainImage;
|
|
1087
|
+
const sandboxTemplate = closure.sandbox === undefined
|
|
1088
|
+
? undefined
|
|
1089
|
+
: {
|
|
1090
|
+
root: "/workspace/.eve/sandbox-cache",
|
|
1091
|
+
digest: closure.sandbox.digest,
|
|
1092
|
+
files: closure.sandbox.files,
|
|
1093
|
+
};
|
|
1024
1094
|
containerRemoved = await removeOwnedContainer(state);
|
|
1025
1095
|
state.containerId = undefined;
|
|
1026
1096
|
cleanupVerified = containerRemoved;
|
|
@@ -1050,7 +1120,14 @@ export async function buildEveRuntimeImage(request) {
|
|
|
1050
1120
|
? {}
|
|
1051
1121
|
: { publicOrigin: request.publicOrigin }),
|
|
1052
1122
|
applicationArtifact: request.candidate.generatedOutput.entrypointPath,
|
|
1053
|
-
runtimeClosure:
|
|
1123
|
+
runtimeClosure: {
|
|
1124
|
+
files: closure.files,
|
|
1125
|
+
nativeModules: closure.nativeModules,
|
|
1126
|
+
outputDigest: closure.outputDigest,
|
|
1127
|
+
dependencyDigest: closure.dependencyDigest,
|
|
1128
|
+
digest: closure.digest,
|
|
1129
|
+
...(sandboxTemplate === undefined ? {} : { sandboxTemplate }),
|
|
1130
|
+
},
|
|
1054
1131
|
health: {
|
|
1055
1132
|
method: "GET",
|
|
1056
1133
|
path: HEALTH_PATH,
|
|
@@ -1085,6 +1162,7 @@ export async function buildEveRuntimeImage(request) {
|
|
|
1085
1162
|
nativeModules: closure.nativeModules,
|
|
1086
1163
|
eveStartClosureRetained: true,
|
|
1087
1164
|
builderOnlyMaterialExcluded: true,
|
|
1165
|
+
...(sandboxTemplate === undefined ? {} : { sandboxTemplate }),
|
|
1088
1166
|
},
|
|
1089
1167
|
};
|
|
1090
1168
|
return {
|
package/dist/eve.d.ts
CHANGED
|
@@ -34,7 +34,6 @@ export interface EveCliExecutionRequest {
|
|
|
34
34
|
/** When true the command prints the machine-readable result object. */
|
|
35
35
|
readonly json?: boolean;
|
|
36
36
|
}
|
|
37
|
-
export type EveCliRunner = (request: EveCliExecutionRequest) => void | Promise<void>;
|
|
38
37
|
export interface EveCliDiagnostic {
|
|
39
38
|
readonly code: string;
|
|
40
39
|
readonly message: string;
|
|
@@ -51,7 +50,7 @@ export declare class EveCliError extends Error {
|
|
|
51
50
|
readonly diagnostics?: readonly EveCliDiagnostic[];
|
|
52
51
|
});
|
|
53
52
|
}
|
|
54
|
-
export declare const
|
|
53
|
+
export declare const EVE_NAME_PATTERN: RegExp;
|
|
55
54
|
export declare function eveHelpText(scope: EveCliHelp["scope"]): string;
|
|
56
55
|
export declare function parseEveArguments(args: readonly string[]): ParsedEveInvocation;
|
|
57
56
|
/**
|
package/dist/eve.js
CHANGED
|
@@ -16,24 +16,7 @@ export class EveCliError extends Error {
|
|
|
16
16
|
this.diagnostics = options.diagnostics ?? [];
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
const EVE_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/u;
|
|
20
|
-
export const EVE_USAGE = `Usage: eden <preflight|deploy|destroy> [options]
|
|
21
|
-
|
|
22
|
-
Eden Deploy commands:
|
|
23
|
-
preflight Build and inspect a local Eve candidate without remote mutation
|
|
24
|
-
deploy Deploy the selected Eve project to the exact named target
|
|
25
|
-
destroy Remove the exact owned Eve target
|
|
26
|
-
|
|
27
|
-
Without flags, preflight and deploy use the current directory, the preview
|
|
28
|
-
environment, and a Worker name derived from the project's package.json name.
|
|
29
|
-
--env accepts only preview or production; production and destroy always
|
|
30
|
-
require an explicit --name. --env-file is accepted only by preflight and deploy.
|
|
31
|
-
All three commands print a human summary by default; --json prints the
|
|
32
|
-
machine-readable result object for scripts and CI.
|
|
33
|
-
|
|
34
|
-
Options:
|
|
35
|
-
--help Show this help
|
|
36
|
-
`;
|
|
19
|
+
export const EVE_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/u;
|
|
37
20
|
const EVE_COMMAND_USAGE = {
|
|
38
21
|
preflight: `Usage: eden preflight [--project <path>] [--env <preview|production>] [--name <name>] [--env-file <path>] [--json]
|
|
39
22
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env -S node --
|
|
2
2
|
import { type EveCliExecutionRequest } from "./eve.js";
|
|
3
3
|
import { type EvePreflightOptions } from "./eve-control-plane.js";
|
|
4
|
-
export { EVE_CLI_COMMANDS,
|
|
4
|
+
export { EVE_CLI_COMMANDS, EveCliError, deriveEveTargetName, eveHelpText, parseEveArguments, } from "./eve.js";
|
|
5
5
|
export { EvePackagingError, buildEveProjectSnapshot, createDockerEveProjectBuilder, revalidateEveProjectCandidateInputs, } from "./eve-packaging.js";
|
|
6
|
-
export { EVE_RESERVED_HOST_VARIABLES, EVE_START_COMMAND, EveRuntimeConfig, EveRuntimeConfigError,
|
|
6
|
+
export { EVE_RESERVED_HOST_VARIABLES, EVE_START_COMMAND, EveRuntimeConfig, EveRuntimeConfigError, prepareEveRuntimeInjection, readEveRuntimeConfig, redactEveRuntimeOutput, } from "./eve-runtime-config.js";
|
|
7
7
|
export type { EveReservedHostVariable, EveRuntimeConfigErrorCode, EveRuntimeInjection, EveRuntimeInjectionMode, EveRuntimeInjectionOptions, EveRuntimeInputIdentity, EveRuntimeProtectedPutRequest, EveRuntimeProtectedPutResult, EveRuntimeProtectedStore, EveStartProcessRequest, RedactedRuntimeConfigSeam, } from "./eve-runtime-config.js";
|
|
8
8
|
export { buildEveRuntimeImage, discardEveRuntimeImage, revalidateEveRuntimeCandidate, validateEveHostRequirements, } from "./eve-runtime-image.js";
|
|
9
|
-
export type { EveCliCommand, EveCliEnvironment, EveCliExecutionRequest, EveCliHelp, EveCliInvocation,
|
|
10
|
-
export type { EveNodeImage, EvePackagingCheck, EvePackagingCode, EveProjectBuilder, EveProjectBuilderRequest, EveProjectBuilderResult, EveProjectBuildCandidate, EveProjectFile, EveProjectImage, EveProjectInputManifest, EveProjectOutput, EveProjectPackagingResult,
|
|
9
|
+
export type { EveCliCommand, EveCliEnvironment, EveCliExecutionRequest, EveCliHelp, EveCliInvocation, ParsedEveInvocation, } from "./eve.js";
|
|
10
|
+
export type { EveNodeImage, EvePackagingCheck, EvePackagingCode, EveProjectBuilder, EveProjectBuilderRequest, EveProjectBuilderResult, EveProjectBuildCandidate, EveProjectFile, EveProjectImage, EveProjectInputManifest, EveProjectOutput, EveProjectPackagingResult, EveProjectSnapshot, EveProjectSnapshotOptions, EveProjectToolchain, EveRuntimeConfigExclusion, EveSandboxResumePatchStatus, } from "./eve-packaging.js";
|
|
11
11
|
export type { EveHostRequirements, EveRuntimeClosure, EveRuntimeClosureFile, EveRuntimeCleanup, EveRuntimeImage, EveRuntimeImageDiscardRequest, EveRuntimeImageMetadata, EveRuntimeImageRequest, EveRuntimeImageResult, EveRuntimeNativeModule, EveRuntimeStatus, } from "./eve-runtime-image.js";
|
|
12
12
|
export { DEFAULT_EVE_HOST_REQUIREMENTS, DEFAULT_EVE_NODE_IMAGE, runEveControlPlane, runEveDestroy, } from "./eve-control-plane.js";
|
|
13
|
-
export type { EveCloudflareReadRequest, EveCloudflareReadResult, EveCloudflareReadRunner, EveCloudflareTargetState, EveContainerDeleteRunner, EveDeploymentCompensationRequest, EveDeploymentCompensationRunner, EveDeploymentHealthRequest, EveDeploymentHealthResult, EveDeploymentHealthRunner, EveDeploymentIdentity, EveDeploymentIdentityProof, EveDeploymentMetadata, EveDeploymentPublicationRequest, EveDeploymentPublicationResult, EveDeploymentPublicationRunner, EveDeploymentStatus, EveDestroyCloudflareReadRequest, EveDestroyCloudflareReadRunner, EveDestroyOutcome, EveDestroyTargetRead, EveImagePublicationRequest, EveImagePublicationResult, EveImagePublicationRunner, EvePreflightCandidate, EvePreflightResult, EvePreflightRuntimeEvidence, EvePreflightWarning, EvePreflightRuntimeRunner, EvePreflightRuntimeRunnerRequest,
|
|
14
|
-
export declare const EDEN_CLI_COMMANDS: readonly ["preflight", "deploy", "destroy"];
|
|
15
|
-
export type EdenCliCommand = (typeof EDEN_CLI_COMMANDS)[number];
|
|
13
|
+
export type { EveCloudflareReadRequest, EveCloudflareReadResult, EveCloudflareReadRunner, EveCloudflareTargetState, EveContainerDeleteRunner, EveDeploymentCompensationRequest, EveDeploymentCompensationRunner, EveDeploymentHealthRequest, EveDeploymentHealthResult, EveDeploymentHealthRunner, EveDeploymentIdentity, EveDeploymentIdentityProof, EveDeploymentMetadata, EveDeploymentPublicationRequest, EveDeploymentPublicationResult, EveDeploymentPublicationRunner, EveDeploymentStatus, EveDestroyCloudflareReadRequest, EveDestroyCloudflareReadRunner, EveDestroyOutcome, EveDestroyTargetRead, EveImagePublicationRequest, EveImagePublicationResult, EveImagePublicationRunner, EvePreflightCandidate, EvePreflightResult, EvePreflightRuntimeEvidence, EvePreflightWarning, EvePreflightRuntimeRunner, EvePreflightRuntimeRunnerRequest, EveRegistryRepositoryDeleteRunner, EveRuntimeConfigLoader, EveRuntimeImageDiscardRunner, EveWorkerDeleteRunner, } from "./eve-control-plane.js";
|
|
16
14
|
export interface EdenCliRunOptions {
|
|
17
15
|
readonly cwd?: string;
|
|
18
16
|
readonly stdout?: (line: string) => void;
|
|
@@ -30,5 +28,4 @@ export interface EdenCliRunOptions {
|
|
|
30
28
|
}
|
|
31
29
|
export declare function runEdenCli(args: readonly string[], options?: EdenCliRunOptions): Promise<number>;
|
|
32
30
|
export declare function main(args?: readonly string[]): Promise<number>;
|
|
33
|
-
export declare function isEdenCliCommand(value: string): value is EdenCliCommand;
|
|
34
31
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -6,16 +6,11 @@ import { fileURLToPath, } from "url";
|
|
|
6
6
|
import { EVE_CLI_COMMANDS, EveCliError, deriveEveTargetName, eveHelpText, parseEveArguments, } from "./eve.js";
|
|
7
7
|
import { EveRuntimeConfigError, readEveRuntimeConfig, redactEveRuntimeOutput, } from "./eve-runtime-config.js";
|
|
8
8
|
import { DEFAULT_EVE_HOST_REQUIREMENTS, runEveControlPlane, runEveDestroy, } from "./eve-control-plane.js";
|
|
9
|
-
export { EVE_CLI_COMMANDS,
|
|
9
|
+
export { EVE_CLI_COMMANDS, EveCliError, deriveEveTargetName, eveHelpText, parseEveArguments, } from "./eve.js";
|
|
10
10
|
export { EvePackagingError, buildEveProjectSnapshot, createDockerEveProjectBuilder, revalidateEveProjectCandidateInputs, } from "./eve-packaging.js";
|
|
11
|
-
export { EVE_RESERVED_HOST_VARIABLES, EVE_START_COMMAND, EveRuntimeConfig, EveRuntimeConfigError,
|
|
11
|
+
export { EVE_RESERVED_HOST_VARIABLES, EVE_START_COMMAND, EveRuntimeConfig, EveRuntimeConfigError, prepareEveRuntimeInjection, readEveRuntimeConfig, redactEveRuntimeOutput, } from "./eve-runtime-config.js";
|
|
12
12
|
export { buildEveRuntimeImage, discardEveRuntimeImage, revalidateEveRuntimeCandidate, validateEveHostRequirements, } from "./eve-runtime-image.js";
|
|
13
13
|
export { DEFAULT_EVE_HOST_REQUIREMENTS, DEFAULT_EVE_NODE_IMAGE, runEveControlPlane, runEveDestroy, } from "./eve-control-plane.js";
|
|
14
|
-
export const EDEN_CLI_COMMANDS = [
|
|
15
|
-
"preflight",
|
|
16
|
-
"deploy",
|
|
17
|
-
"destroy",
|
|
18
|
-
];
|
|
19
14
|
const USAGE = `Usage: eden <command> [options]
|
|
20
15
|
|
|
21
16
|
Commands:
|
|
@@ -193,9 +188,6 @@ export async function runEdenCli(args, options = {}) {
|
|
|
193
188
|
export async function main(args = process.argv.slice(2)) {
|
|
194
189
|
return runEdenCli(args);
|
|
195
190
|
}
|
|
196
|
-
export function isEdenCliCommand(value) {
|
|
197
|
-
return EDEN_CLI_COMMANDS.includes(value);
|
|
198
|
-
}
|
|
199
191
|
if (process.argv[1] !== undefined &&
|
|
200
192
|
realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) {
|
|
201
193
|
void main().then((exitCode) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moinulmoin/eden",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Deploy existing Eve projects to your own Cloudflare account.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"NOTICE"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@moinulmoin/eden-runtime-cloudflare": "0.
|
|
35
|
-
"wrangler": "4.
|
|
34
|
+
"@moinulmoin/eden-runtime-cloudflare": "0.7.0",
|
|
35
|
+
"wrangler": "4.147.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "24.0.0"
|