@tangle-network/agent-app 0.39.0 → 0.39.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/{auth-BlS9GWfL.d.ts → auth-DcK5ERaL.d.ts} +7 -4
- package/dist/{chunk-IOREXWLM.js → chunk-2FDTJIU4.js} +8 -35
- package/dist/{chunk-IOREXWLM.js.map → chunk-2FDTJIU4.js.map} +1 -1
- package/dist/{chunk-JT6HHO5P.js → chunk-BUUJ7TEQ.js} +8 -33
- package/dist/{chunk-JT6HHO5P.js.map → chunk-BUUJ7TEQ.js.map} +1 -1
- package/dist/{chunk-CDYYR3Z7.js → chunk-DBIG2PHS.js} +208 -36
- package/dist/chunk-DBIG2PHS.js.map +1 -0
- package/dist/{chunk-VT5DI6GL.js → chunk-FDJ6JQCI.js} +3 -3
- package/dist/{chunk-JZZ6AWF4.js → chunk-PPSZNVKT.js} +9 -7
- package/dist/chunk-PPSZNVKT.js.map +1 -0
- package/dist/{chunk-A76ZHWNF.js → chunk-RH74YJIK.js} +31 -1
- package/dist/chunk-RH74YJIK.js.map +1 -0
- package/dist/{chunk-4IQMTTNE.js → chunk-TQ5M7BFV.js} +2 -2
- package/dist/design-canvas/index.d.ts +8 -21
- package/dist/design-canvas/index.js +2 -2
- package/dist/eval/index.d.ts +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +12 -9
- package/dist/{mcp-BShTlESm.d.ts → mcp-4I_RHhNa.d.ts} +38 -3
- package/dist/preset-cloudflare/index.d.ts +1 -1
- package/dist/runtime/index.d.ts +3 -3
- package/dist/runtime/index.js +2 -2
- package/dist/sandbox/index.d.ts +7 -3
- package/dist/sandbox/index.js +6 -4
- package/dist/sequences/index.d.ts +10 -27
- package/dist/sequences/index.js +5 -4
- package/dist/tools/index.d.ts +5 -5
- package/dist/tools/index.js +5 -3
- package/dist/{types-2rOJo8Hc.d.ts → types-wHs0rmtu.d.ts} +12 -1
- package/package.json +1 -1
- package/dist/chunk-A76ZHWNF.js.map +0 -1
- package/dist/chunk-CDYYR3Z7.js.map +0 -1
- package/dist/chunk-JZZ6AWF4.js.map +0 -1
- /package/dist/{chunk-VT5DI6GL.js.map → chunk-FDJ6JQCI.js.map} +0 -0
- /package/dist/{chunk-4IQMTTNE.js.map → chunk-TQ5M7BFV.js.map} +0 -0
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
base64UrlEncodeText,
|
|
7
7
|
constantTimeEqual,
|
|
8
8
|
hmacSha256Base64Url
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FDJ6JQCI.js";
|
|
10
10
|
import {
|
|
11
11
|
buildAppToolMcpServer
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-RH74YJIK.js";
|
|
13
13
|
import {
|
|
14
14
|
resolveTangleExecutionEnvironment,
|
|
15
15
|
trimOrNull
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
import {
|
|
20
20
|
Sandbox
|
|
21
21
|
} from "@tangle-network/sandbox";
|
|
22
|
+
import { createHash } from "crypto";
|
|
22
23
|
|
|
23
24
|
// src/sandbox/outcome.ts
|
|
24
25
|
var ok = (value) => ({ succeeded: true, value });
|
|
@@ -592,21 +593,70 @@ function execWithTimeout(box, cmd, timeoutMs) {
|
|
|
592
593
|
);
|
|
593
594
|
});
|
|
594
595
|
}
|
|
596
|
+
var TRANSIENT_EXEC_STATUS_CODES = /* @__PURE__ */ new Set([408, 409, 425, 429, 500, 502, 503, 504]);
|
|
597
|
+
var TRANSIENT_EXEC_CODE_RE = /^(ECONNRESET|ECONNREFUSED|ETIMEDOUT|EPIPE|ECONNABORTED)$/i;
|
|
598
|
+
var TRANSIENT_EXEC_MESSAGE_RE = /\b(408|409|425|429|500|502|503|504)\b|rate.?limit|too many requests|\bfetch failed\b|network error|connection reset|socket hang up|timed? out|service unavailable|bad gateway|gateway timeout|internal server error|\b(?:sidecar|runtime|exec(?:ution)?|terminal|sandbox|service|command(?:s)?|proxy)\b.{0,80}\bnot ready\b|\bnot ready\b.{0,80}\b(?:sidecar|runtime|exec(?:ution)?|terminal|sandbox|service|command(?:s)?|proxy)\b/i;
|
|
599
|
+
var RUNTIME_AUTH_REFRESH_SKEW_MS = 6e4;
|
|
600
|
+
function errorStatus(err) {
|
|
601
|
+
const rawStatus = err.status ?? err.statusCode ?? (err.response && typeof err.response === "object" ? err.response.status : void 0);
|
|
602
|
+
if (typeof rawStatus === "number") return rawStatus;
|
|
603
|
+
if (typeof rawStatus === "string" && /^\d+$/.test(rawStatus)) return Number(rawStatus);
|
|
604
|
+
return void 0;
|
|
605
|
+
}
|
|
606
|
+
function retryAfterMs(err, seen = /* @__PURE__ */ new Set()) {
|
|
607
|
+
if (!err || typeof err !== "object") return void 0;
|
|
608
|
+
if (seen.has(err)) return void 0;
|
|
609
|
+
seen.add(err);
|
|
610
|
+
const e = err;
|
|
611
|
+
if (typeof e.retryAfterMs === "number") return e.retryAfterMs;
|
|
612
|
+
return retryAfterMs(e.cause, seen);
|
|
613
|
+
}
|
|
614
|
+
function isTransientExecError(err, seen = /* @__PURE__ */ new Set()) {
|
|
615
|
+
if (!err || typeof err !== "object") return false;
|
|
616
|
+
if (seen.has(err)) return false;
|
|
617
|
+
seen.add(err);
|
|
618
|
+
const e = err;
|
|
619
|
+
const status = errorStatus(e);
|
|
620
|
+
if (status !== void 0 && TRANSIENT_EXEC_STATUS_CODES.has(status)) return true;
|
|
621
|
+
if (typeof e.code === "string") {
|
|
622
|
+
if (TRANSIENT_EXEC_CODE_RE.test(e.code)) return true;
|
|
623
|
+
if (/rate.?limit|too.?many.?requests|429|server.?error|service.?unavailable/i.test(e.code)) return true;
|
|
624
|
+
}
|
|
625
|
+
if (typeof e.message === "string" && TRANSIENT_EXEC_MESSAGE_RE.test(e.message)) return true;
|
|
626
|
+
return isTransientExecError(e.cause, seen);
|
|
627
|
+
}
|
|
628
|
+
function isRuntimeExecAuthError(err, seen = /* @__PURE__ */ new Set()) {
|
|
629
|
+
if (!err || typeof err !== "object") return false;
|
|
630
|
+
if (seen.has(err)) return false;
|
|
631
|
+
seen.add(err);
|
|
632
|
+
const e = err;
|
|
633
|
+
if (errorStatus(e) === 401) return true;
|
|
634
|
+
if (typeof e.code === "string" && /^(AUTH_ERROR|AUTHENTICATION_ERROR|UNAUTHORIZED|UNAUTHENTICATED|ERR_UNAUTHORIZED|ERR_UNAUTHENTICATED|401)$/i.test(e.code)) {
|
|
635
|
+
return true;
|
|
636
|
+
}
|
|
637
|
+
if (typeof e.name === "string" && /^(AuthError|AuthenticationError|UnauthorizedError|UnauthenticatedError|SandboxAuthError)$/i.test(e.name)) {
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
return isRuntimeExecAuthError(e.cause, seen);
|
|
641
|
+
}
|
|
642
|
+
function isRuntimeAuthRefreshDenied(err) {
|
|
643
|
+
if (!err || typeof err !== "object") return false;
|
|
644
|
+
return isRuntimeExecAuthError(err) || errorStatus(err) === 403;
|
|
645
|
+
}
|
|
595
646
|
function transientExecError(err) {
|
|
596
647
|
if (err instanceof ProfileWriteExecTimeoutError) return { retryable: true };
|
|
597
|
-
if (err
|
|
598
|
-
const e = err;
|
|
599
|
-
const retryAfterMs = typeof e.retryAfterMs === "number" ? e.retryAfterMs : void 0;
|
|
600
|
-
if (e.status === 429) return { retryable: true, retryAfterMs };
|
|
601
|
-
if (typeof e.code === "string" && /rate.?limit|too.?many.?requests|429/i.test(e.code)) {
|
|
602
|
-
return { retryable: true, retryAfterMs };
|
|
603
|
-
}
|
|
604
|
-
if (typeof e.message === "string" && /\b429\b|rate.?limit|too many requests/i.test(e.message)) {
|
|
605
|
-
return { retryable: true, retryAfterMs };
|
|
606
|
-
}
|
|
607
|
-
}
|
|
648
|
+
if (isTransientExecError(err)) return { retryable: true, retryAfterMs: retryAfterMs(err) };
|
|
608
649
|
return { retryable: false };
|
|
609
650
|
}
|
|
651
|
+
function deferredProfileWriteFailed(stage, name, cause) {
|
|
652
|
+
return new Error(`deferred file write failed on ${stage} box ${name}: ${cause.message}`, { cause });
|
|
653
|
+
}
|
|
654
|
+
var SandboxRuntimeAuthRefreshError = class extends Error {
|
|
655
|
+
constructor(stage, name, detail, cause) {
|
|
656
|
+
super(`${stage} sandbox auth refresh failed for ${name}: ${detail}`, { cause });
|
|
657
|
+
this.name = "SandboxRuntimeAuthRefreshError";
|
|
658
|
+
}
|
|
659
|
+
};
|
|
610
660
|
async function writeProfileFilesToBox(box, files, options = {}) {
|
|
611
661
|
const execTimeoutMs = options.execTimeoutMs ?? PROFILE_WRITE_EXEC_TIMEOUT_MS;
|
|
612
662
|
const paceMs = options.paceMs ?? PROFILE_WRITE_PACE_MS;
|
|
@@ -616,12 +666,19 @@ async function writeProfileFilesToBox(box, files, options = {}) {
|
|
|
616
666
|
if (mount.resource.kind !== "inline") continue;
|
|
617
667
|
const content = mount.resource.content ?? "";
|
|
618
668
|
const b64 = Buffer.from(content, "utf8").toString("base64");
|
|
669
|
+
const b64Chunks = [];
|
|
670
|
+
for (let i = 0; i < b64.length; i += PROFILE_WRITE_B64_CHUNK_CHARS) {
|
|
671
|
+
b64Chunks.push(b64.slice(i, i + PROFILE_WRITE_B64_CHUNK_CHARS));
|
|
672
|
+
}
|
|
673
|
+
const expectedSha256 = createHash("sha256").update(content, "utf8").digest("hex");
|
|
619
674
|
const path = mount.path;
|
|
620
675
|
const dir = path.replace(/\/[^/]*$/, "");
|
|
621
676
|
const isBin = /(^|\/)(s?bin)\//.test(path);
|
|
622
677
|
const executable = mount.executable ?? isBin;
|
|
623
678
|
const q = shellPath(path);
|
|
624
679
|
const qb64 = shellPath(`${path}.b64`);
|
|
680
|
+
const qtmp = shellPath(`${path}.tmp`);
|
|
681
|
+
const qpartPrefix = shellPath(`${path}.b64.part.`);
|
|
625
682
|
const step = async (cmd) => {
|
|
626
683
|
for (let attempt = 0; ; attempt++) {
|
|
627
684
|
if (execStarted && paceMs > 0) await sleep(paceMs);
|
|
@@ -637,35 +694,37 @@ async function writeProfileFilesToBox(box, files, options = {}) {
|
|
|
637
694
|
}
|
|
638
695
|
return ok(void 0);
|
|
639
696
|
} catch (err) {
|
|
640
|
-
const { retryable, retryAfterMs } = transientExecError(err);
|
|
697
|
+
const { retryable, retryAfterMs: retryAfterMs2 } = transientExecError(err);
|
|
641
698
|
if (retryable && attempt < maxRetries) {
|
|
642
699
|
const backoff = Math.min(
|
|
643
700
|
PROFILE_WRITE_RETRY_BASE_MS * 2 ** attempt,
|
|
644
701
|
PROFILE_WRITE_RETRY_MAX_MS
|
|
645
702
|
);
|
|
646
|
-
await sleep(
|
|
703
|
+
await sleep(retryAfterMs2 ?? backoff);
|
|
647
704
|
continue;
|
|
648
705
|
}
|
|
649
706
|
return fail(new Error(`writeProfileFilesToBox: exec failed for ${path}`, { cause: err }));
|
|
650
707
|
}
|
|
651
708
|
}
|
|
652
709
|
};
|
|
653
|
-
const mkdir = dir && dir !== path ? `mkdir -p ${shellPath(dir)}
|
|
654
|
-
let res = await step(
|
|
710
|
+
const mkdir = dir && dir !== path ? `mkdir -p ${shellPath(dir)}` : ":";
|
|
711
|
+
let res = await step(mkdir);
|
|
655
712
|
if (!res.succeeded) return res;
|
|
656
|
-
for (let i = 0; i <
|
|
657
|
-
const slice =
|
|
658
|
-
res = await step(`printf '%s' '${slice}'
|
|
713
|
+
for (let i = 0; i < b64Chunks.length; i++) {
|
|
714
|
+
const slice = b64Chunks[i];
|
|
715
|
+
res = await step(`printf '%s' '${slice}' > ${shellPath(`${path}.b64.part.${i}`)}`);
|
|
659
716
|
if (!res.succeeded) return res;
|
|
660
717
|
}
|
|
661
|
-
const chmod = executable ? `
|
|
662
|
-
|
|
718
|
+
const chmod = executable ? `chmod +x ${q} || exit 1; ` : "";
|
|
719
|
+
const checksumMismatch = shellSingleQuote(`writeProfileFilesToBox: checksum mismatch for ${path}`);
|
|
720
|
+
const finalCmd = `expected='${expectedSha256}'; if [ -f ${q} ] && [ "$(sha256sum ${q} | awk '{print $1}')" = "$expected" ]; then ${chmod}rm -f ${qb64} ${qtmp}; i=0; while [ "$i" -lt ${b64Chunks.length} ]; do rm -f ${qpartPrefix}$i; i=$((i+1)); done; exit 0; fi; : > ${qb64} && i=0; while [ "$i" -lt ${b64Chunks.length} ]; do cat ${qpartPrefix}$i >> ${qb64} || exit 1; i=$((i+1)); done && base64 -d ${qb64} > ${qtmp} && [ "$(sha256sum ${qtmp} | awk '{print $1}')" = "$expected" ] || { echo ${checksumMismatch} >&2; exit 1; }; mv ${qtmp} ${q} && ${executable ? `chmod +x ${q} && ` : ""}[ "$(sha256sum ${q} | awk '{print $1}')" = "$expected" ] || { echo ${checksumMismatch} >&2; exit 1; }; rm -f ${qb64} ${qtmp}; i=0; while [ "$i" -lt ${b64Chunks.length} ]; do rm -f ${qpartPrefix}$i; i=$((i+1)); done`;
|
|
721
|
+
res = await step(finalCmd);
|
|
663
722
|
if (!res.succeeded) return res;
|
|
664
723
|
}
|
|
665
724
|
return ok(void 0);
|
|
666
725
|
}
|
|
667
|
-
async function materializeDeferredFilesForExistingBox(shell, box, workspaceId, userId) {
|
|
668
|
-
if (!shell.deferProfileFiles) return ok(
|
|
726
|
+
async function materializeDeferredFilesForExistingBox(shell, client, box, stage, name, workspaceId, userId) {
|
|
727
|
+
if (!shell.deferProfileFiles) return ok(box);
|
|
669
728
|
const connectedIntegrationIds = await shell.connectedIntegrationIds(workspaceId);
|
|
670
729
|
const buildCtx = {
|
|
671
730
|
workspaceId,
|
|
@@ -675,8 +734,8 @@ async function materializeDeferredFilesForExistingBox(shell, box, workspaceId, u
|
|
|
675
734
|
const files = await shell.files(buildCtx);
|
|
676
735
|
const fullProfile = shell.profile({ extraFiles: files });
|
|
677
736
|
const { deferredFiles } = splitDeferredProfileFiles(fullProfile);
|
|
678
|
-
if (deferredFiles.length === 0) return ok(
|
|
679
|
-
return
|
|
737
|
+
if (deferredFiles.length === 0) return ok(box);
|
|
738
|
+
return writeDeferredFilesWithRuntimeAuthRefresh(client, box, deferredFiles, stage, name);
|
|
680
739
|
}
|
|
681
740
|
async function listRunning(client, name) {
|
|
682
741
|
try {
|
|
@@ -726,6 +785,22 @@ function sandboxRuntimeUrl(box) {
|
|
|
726
785
|
const connection = box.connection;
|
|
727
786
|
return connection?.sidecarUrl ?? connection?.runtimeUrl;
|
|
728
787
|
}
|
|
788
|
+
function runtimeAuthExpiresAtMs(value) {
|
|
789
|
+
if (value instanceof Date) return value.getTime();
|
|
790
|
+
if (typeof value === "number") return value;
|
|
791
|
+
if (typeof value !== "string" || value.trim() === "") return void 0;
|
|
792
|
+
const parsed = Date.parse(value);
|
|
793
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
794
|
+
}
|
|
795
|
+
function hasFreshRuntimeExecAuth(box, now = Date.now()) {
|
|
796
|
+
const connection = box.connection;
|
|
797
|
+
const token = connection?.authToken ?? connection?.sidecarToken;
|
|
798
|
+
if (!sandboxRuntimeUrl(box) || !token) return false;
|
|
799
|
+
const expiresAt = runtimeAuthExpiresAtMs(
|
|
800
|
+
connection?.authTokenExpiresAt ?? connection?.sidecarTokenExpiresAt
|
|
801
|
+
);
|
|
802
|
+
return expiresAt === void 0 || expiresAt > now + RUNTIME_AUTH_REFRESH_SKEW_MS;
|
|
803
|
+
}
|
|
729
804
|
function sandboxEdgeFailed(box) {
|
|
730
805
|
const connection = box.connection;
|
|
731
806
|
return connection?.edgeStatus === "failed" || Boolean(connection?.edgeError);
|
|
@@ -747,6 +822,84 @@ async function refreshRuntimeConnection(client, box) {
|
|
|
747
822
|
}
|
|
748
823
|
return current;
|
|
749
824
|
}
|
|
825
|
+
async function bestEffortRefreshRuntimeExecAuth(client, box, stage, name) {
|
|
826
|
+
let current = box;
|
|
827
|
+
try {
|
|
828
|
+
await current.refresh();
|
|
829
|
+
if (hasFreshRuntimeExecAuth(current)) return ok(current);
|
|
830
|
+
} catch (err) {
|
|
831
|
+
if (isRuntimeAuthRefreshDenied(err)) {
|
|
832
|
+
return fail(
|
|
833
|
+
new SandboxRuntimeAuthRefreshError(
|
|
834
|
+
stage,
|
|
835
|
+
name,
|
|
836
|
+
"runtime exec auth refresh was unauthorized",
|
|
837
|
+
err
|
|
838
|
+
)
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
try {
|
|
843
|
+
const latest = await client.get(current.id);
|
|
844
|
+
if (latest) current = latest;
|
|
845
|
+
if (hasFreshRuntimeExecAuth(current)) return ok(current);
|
|
846
|
+
} catch (err) {
|
|
847
|
+
if (isRuntimeAuthRefreshDenied(err)) {
|
|
848
|
+
return fail(
|
|
849
|
+
new SandboxRuntimeAuthRefreshError(
|
|
850
|
+
stage,
|
|
851
|
+
name,
|
|
852
|
+
"runtime exec auth re-fetch was unauthorized",
|
|
853
|
+
err
|
|
854
|
+
)
|
|
855
|
+
);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
return ok(current);
|
|
859
|
+
}
|
|
860
|
+
async function refreshRuntimeExecAuth(client, box, stage, name) {
|
|
861
|
+
let current = box;
|
|
862
|
+
let lastError;
|
|
863
|
+
const deadline = Date.now() + RUNTIME_CONNECTION_WAIT_MS;
|
|
864
|
+
while (Date.now() < deadline) {
|
|
865
|
+
try {
|
|
866
|
+
await current.refresh();
|
|
867
|
+
if (hasFreshRuntimeExecAuth(current)) return ok(current);
|
|
868
|
+
const latest = await client.get(current.id);
|
|
869
|
+
if (latest) current = latest;
|
|
870
|
+
if (hasFreshRuntimeExecAuth(current)) return ok(current);
|
|
871
|
+
} catch (err) {
|
|
872
|
+
lastError = err;
|
|
873
|
+
}
|
|
874
|
+
await new Promise((resolve) => setTimeout(resolve, RUNTIME_CONNECTION_POLL_MS));
|
|
875
|
+
}
|
|
876
|
+
const detail = sandboxRuntimeUrl(current) ? "runtime exec credentials are missing or expired after refresh" : "runtime connection is missing after refresh";
|
|
877
|
+
return fail(new SandboxRuntimeAuthRefreshError(stage, name, detail, lastError));
|
|
878
|
+
}
|
|
879
|
+
async function writeDeferredFilesWithRuntimeAuthRefresh(client, box, files, stage, name) {
|
|
880
|
+
let writeBox = box;
|
|
881
|
+
if (!hasFreshRuntimeExecAuth(writeBox)) {
|
|
882
|
+
const refreshed2 = await bestEffortRefreshRuntimeExecAuth(client, writeBox, stage, name);
|
|
883
|
+
if (!refreshed2.succeeded) return fail(refreshed2.error);
|
|
884
|
+
writeBox = refreshed2.value;
|
|
885
|
+
}
|
|
886
|
+
const first = await writeProfileFilesToBox(writeBox, files);
|
|
887
|
+
if (first.succeeded) return ok(writeBox);
|
|
888
|
+
if (!isRuntimeExecAuthError(first.error)) return fail(first.error);
|
|
889
|
+
const refreshed = await refreshRuntimeExecAuth(client, writeBox, stage, name);
|
|
890
|
+
if (!refreshed.succeeded) return fail(refreshed.error);
|
|
891
|
+
const second = await writeProfileFilesToBox(refreshed.value, files);
|
|
892
|
+
if (second.succeeded) return ok(refreshed.value);
|
|
893
|
+
if (!isRuntimeExecAuthError(second.error)) return fail(second.error);
|
|
894
|
+
return fail(
|
|
895
|
+
new SandboxRuntimeAuthRefreshError(
|
|
896
|
+
stage,
|
|
897
|
+
name,
|
|
898
|
+
"runtime exec remained unauthorized after auth refresh",
|
|
899
|
+
second.error
|
|
900
|
+
)
|
|
901
|
+
);
|
|
902
|
+
}
|
|
750
903
|
async function isReusableBox(box, harness, probe) {
|
|
751
904
|
if (sandboxEdgeFailed(box)) return false;
|
|
752
905
|
if (!sandboxRuntimeUrl(box)) return false;
|
|
@@ -784,17 +937,26 @@ async function ensureWorkspaceSandbox(shell, options) {
|
|
|
784
937
|
} else if (found.metadata?.harness === harness) {
|
|
785
938
|
const ready = await refreshRuntimeConnection(client, found);
|
|
786
939
|
if (await isReusableBox(ready, harness, shell.livenessProbe)) {
|
|
787
|
-
const written = await materializeDeferredFilesForExistingBox(
|
|
940
|
+
const written = await materializeDeferredFilesForExistingBox(
|
|
941
|
+
shell,
|
|
942
|
+
client,
|
|
943
|
+
ready,
|
|
944
|
+
"reused",
|
|
945
|
+
name,
|
|
946
|
+
workspaceId,
|
|
947
|
+
userId
|
|
948
|
+
);
|
|
788
949
|
if (!written.succeeded) {
|
|
789
|
-
throw
|
|
950
|
+
throw deferredProfileWriteFailed("reused", name, written.error);
|
|
790
951
|
}
|
|
952
|
+
const reusedBox = written.value;
|
|
791
953
|
if (shell.bootstrap) {
|
|
792
|
-
const boot = await shell.bootstrap(
|
|
954
|
+
const boot = await shell.bootstrap(reusedBox, scope);
|
|
793
955
|
if (!boot.succeeded) {
|
|
794
956
|
throw new Error(`bootstrap failed on reused box ${name}`, { cause: boot.error });
|
|
795
957
|
}
|
|
796
958
|
}
|
|
797
|
-
return
|
|
959
|
+
return reusedBox;
|
|
798
960
|
}
|
|
799
961
|
const dropped = await deleteBox(ready);
|
|
800
962
|
if (!dropped.succeeded) {
|
|
@@ -818,17 +980,26 @@ async function ensureWorkspaceSandbox(shell, options) {
|
|
|
818
980
|
if (resumed.succeeded && resumed.value) {
|
|
819
981
|
const box2 = await refreshRuntimeConnection(client, resumed.value);
|
|
820
982
|
if (await isReusableBox(box2, harness, shell.livenessProbe)) {
|
|
821
|
-
const written = await materializeDeferredFilesForExistingBox(
|
|
983
|
+
const written = await materializeDeferredFilesForExistingBox(
|
|
984
|
+
shell,
|
|
985
|
+
client,
|
|
986
|
+
box2,
|
|
987
|
+
"resumed",
|
|
988
|
+
name,
|
|
989
|
+
workspaceId,
|
|
990
|
+
userId
|
|
991
|
+
);
|
|
822
992
|
if (!written.succeeded) {
|
|
823
|
-
throw
|
|
993
|
+
throw deferredProfileWriteFailed("resumed", name, written.error);
|
|
824
994
|
}
|
|
995
|
+
const resumedBox = written.value;
|
|
825
996
|
if (shell.bootstrap) {
|
|
826
|
-
const boot = await shell.bootstrap(
|
|
997
|
+
const boot = await shell.bootstrap(resumedBox, scope);
|
|
827
998
|
if (!boot.succeeded) {
|
|
828
999
|
throw new Error(`bootstrap failed on resumed box ${name}`, { cause: boot.error });
|
|
829
1000
|
}
|
|
830
1001
|
}
|
|
831
|
-
return
|
|
1002
|
+
return resumedBox;
|
|
832
1003
|
}
|
|
833
1004
|
const dropped = await deleteBox(box2);
|
|
834
1005
|
if (!dropped.succeeded) {
|
|
@@ -892,7 +1063,7 @@ async function ensureWorkspaceSandbox(shell, options) {
|
|
|
892
1063
|
if (deferredFiles.length > 0) {
|
|
893
1064
|
const written = await writeProfileFilesToBox(box, deferredFiles);
|
|
894
1065
|
if (!written.succeeded) {
|
|
895
|
-
throw
|
|
1066
|
+
throw deferredProfileWriteFailed("new", name, written.error);
|
|
896
1067
|
}
|
|
897
1068
|
}
|
|
898
1069
|
if (shell.bootstrap) {
|
|
@@ -1190,6 +1361,7 @@ export {
|
|
|
1190
1361
|
buildSandboxToolPathSetupScript,
|
|
1191
1362
|
runSandboxToolPathSetup,
|
|
1192
1363
|
splitDeferredProfileFiles,
|
|
1364
|
+
SandboxRuntimeAuthRefreshError,
|
|
1193
1365
|
writeProfileFilesToBox,
|
|
1194
1366
|
ensureWorkspaceSandbox,
|
|
1195
1367
|
resolveModel,
|
|
@@ -1211,4 +1383,4 @@ export {
|
|
|
1211
1383
|
isTerminalPromptEvent,
|
|
1212
1384
|
detectInteractiveQuestion
|
|
1213
1385
|
};
|
|
1214
|
-
//# sourceMappingURL=chunk-
|
|
1386
|
+
//# sourceMappingURL=chunk-DBIG2PHS.js.map
|