@madarco/agentbox 0.14.0 → 0.15.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/CHANGELOG.md +60 -0
- package/dist/{_cloud-attach-GUBB5RH2.js → _cloud-attach-R6TRWG5L.js} +3 -3
- package/dist/{chunk-BYCLD6D6.js → chunk-43Q5GWP6.js} +98 -54
- package/dist/chunk-43Q5GWP6.js.map +1 -0
- package/dist/{chunk-VATTS2MR.js → chunk-72CJTXN6.js} +2 -2
- package/dist/{chunk-TBSIJVSN.js → chunk-E7CHS7ZR.js} +21 -13
- package/dist/chunk-E7CHS7ZR.js.map +1 -0
- package/dist/{chunk-LDMYHWUS.js → chunk-MCOU6CZS.js} +2 -2
- package/dist/{chunk-TCS5HXJX.js → chunk-MLMFNN4T.js} +396 -324
- package/dist/chunk-MLMFNN4T.js.map +1 -0
- package/dist/{dist-J2IHD5T7.js → dist-AGTIA7AD.js} +3 -3
- package/dist/{dist-3IMQNTTV.js → dist-FIFEFKJ7.js} +3 -3
- package/dist/{dist-34RKQ74M.js → dist-JZ3XO6EB.js} +4 -4
- package/dist/{dist-4DPOL5A7.js → dist-OGJGZETZ.js} +2 -2
- package/dist/{dist-57M6ZA7H.js → dist-S4XR4ACV.js} +4 -4
- package/dist/index.js +868 -300
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +30 -0
- package/runtime/docker/packages/ctl/dist/bin.cjs +321 -27
- package/runtime/e2b/agentbox-setup-skill.md +30 -0
- package/runtime/e2b/ctl.cjs +321 -27
- package/runtime/hetzner/agentbox-setup-skill.md +30 -0
- package/runtime/hetzner/ctl.cjs +321 -27
- package/runtime/relay/bin.cjs +83 -5
- package/runtime/vercel/agentbox-setup-skill.md +30 -0
- package/runtime/vercel/ctl.cjs +321 -27
- package/share/agentbox-setup/SKILL.md +30 -0
- package/share/host-skills/agentbox-info/SKILL.md +21 -1
- package/dist/chunk-BYCLD6D6.js.map +0 -1
- package/dist/chunk-TBSIJVSN.js.map +0 -1
- package/dist/chunk-TCS5HXJX.js.map +0 -1
- /package/dist/{_cloud-attach-GUBB5RH2.js.map → _cloud-attach-R6TRWG5L.js.map} +0 -0
- /package/dist/{chunk-VATTS2MR.js.map → chunk-72CJTXN6.js.map} +0 -0
- /package/dist/{chunk-LDMYHWUS.js.map → chunk-MCOU6CZS.js.map} +0 -0
- /package/dist/{dist-J2IHD5T7.js.map → dist-AGTIA7AD.js.map} +0 -0
- /package/dist/{dist-3IMQNTTV.js.map → dist-FIFEFKJ7.js.map} +0 -0
- /package/dist/{dist-34RKQ74M.js.map → dist-JZ3XO6EB.js.map} +0 -0
- /package/dist/{dist-4DPOL5A7.js.map → dist-OGJGZETZ.js.map} +0 -0
- /package/dist/{dist-57M6ZA7H.js.map → dist-S4XR4ACV.js.map} +0 -0
|
@@ -24,8 +24,8 @@ import {
|
|
|
24
24
|
// ../../packages/sandbox-docker/dist/index.js
|
|
25
25
|
import { mkdir as mkdir7, stat as stat8 } from "fs/promises";
|
|
26
26
|
import { homedir as homedir10 } from "os";
|
|
27
|
-
import { basename as
|
|
28
|
-
import { execa as
|
|
27
|
+
import { basename as basename5, join as join12, resolve as resolve4 } from "path";
|
|
28
|
+
import { execa as execa15 } from "execa";
|
|
29
29
|
|
|
30
30
|
// ../../packages/ctl/dist/index.js
|
|
31
31
|
import { readFile } from "fs/promises";
|
|
@@ -517,7 +517,21 @@ var CarryConfigError = class extends Error {
|
|
|
517
517
|
this.name = "CarryConfigError";
|
|
518
518
|
}
|
|
519
519
|
};
|
|
520
|
-
var ITEM_KEYS = /* @__PURE__ */ new Set(["src", "dest", "mode", "user", "optional"]);
|
|
520
|
+
var ITEM_KEYS = /* @__PURE__ */ new Set(["src", "dest", "mode", "user", "exclude", "optional"]);
|
|
521
|
+
function parseExclude(raw, where) {
|
|
522
|
+
if (raw === void 0 || raw === null) return void 0;
|
|
523
|
+
if (!Array.isArray(raw)) {
|
|
524
|
+
throw new CarryConfigError(`${where}.exclude must be a list of glob/name strings`);
|
|
525
|
+
}
|
|
526
|
+
const out = [];
|
|
527
|
+
for (const [i, v] of raw.entries()) {
|
|
528
|
+
if (typeof v !== "string" || v.trim().length === 0) {
|
|
529
|
+
throw new CarryConfigError(`${where}.exclude[${String(i)}] must be a non-empty string`);
|
|
530
|
+
}
|
|
531
|
+
out.push(v.trim());
|
|
532
|
+
}
|
|
533
|
+
return out.length > 0 ? out : void 0;
|
|
534
|
+
}
|
|
521
535
|
function parseUser(raw, where) {
|
|
522
536
|
if (raw === void 0 || raw === null) return void 0;
|
|
523
537
|
let n;
|
|
@@ -646,6 +660,7 @@ function parseMapping(raw, where) {
|
|
|
646
660
|
assertDestShape(dest, where);
|
|
647
661
|
const mode = parseMode(raw.mode, where);
|
|
648
662
|
const user = parseUser(raw.user, where);
|
|
663
|
+
const exclude = parseExclude(raw.exclude, where);
|
|
649
664
|
let optional = false;
|
|
650
665
|
if (raw.optional !== void 0 && raw.optional !== null) {
|
|
651
666
|
if (typeof raw.optional !== "boolean") {
|
|
@@ -656,6 +671,7 @@ function parseMapping(raw, where) {
|
|
|
656
671
|
const out = { src, dest, optional };
|
|
657
672
|
if (mode !== void 0) out.mode = mode;
|
|
658
673
|
if (user !== void 0) out.user = user;
|
|
674
|
+
if (exclude !== void 0) out.exclude = exclude;
|
|
659
675
|
return out;
|
|
660
676
|
}
|
|
661
677
|
function parseCarryRaw(raw) {
|
|
@@ -702,20 +718,6 @@ async function loadCarrySection(path) {
|
|
|
702
718
|
return parseCarrySection(text);
|
|
703
719
|
}
|
|
704
720
|
|
|
705
|
-
// ../../packages/sandbox-docker/dist/index.js
|
|
706
|
-
import { spawnSync } from "child_process";
|
|
707
|
-
import { mkdir as mkdir3, mkdtemp as mkdtemp2, readdir as readdir3, readFile as readFile42, realpath as realpath2, rm as rm2, stat as stat3, writeFile as writeFile22 } from "fs/promises";
|
|
708
|
-
import { homedir as homedir3, tmpdir as tmpdir2 } from "os";
|
|
709
|
-
import { isAbsolute as isAbsolute2, join as join4, relative as relative2 } from "path";
|
|
710
|
-
import { setTimeout as delay } from "timers/promises";
|
|
711
|
-
import { execa as execa5 } from "execa";
|
|
712
|
-
import { execa as execa2 } from "execa";
|
|
713
|
-
import { mkdir as mkdir4, readFile as readFile5, readdir as readdir4, stat as stat4 } from "fs/promises";
|
|
714
|
-
import { createHash as createHash3 } from "crypto";
|
|
715
|
-
import { homedir as homedir2 } from "os";
|
|
716
|
-
import { join as join5 } from "path";
|
|
717
|
-
import { execa as execa22 } from "execa";
|
|
718
|
-
|
|
719
721
|
// ../../packages/config/dist/index.js
|
|
720
722
|
import { parse as parseYaml3 } from "yaml";
|
|
721
723
|
import { createHash } from "crypto";
|
|
@@ -748,6 +750,7 @@ var BUILT_IN_DEFAULTS = {
|
|
|
748
750
|
withEnv: false,
|
|
749
751
|
resyncOnStart: true,
|
|
750
752
|
vnc: true,
|
|
753
|
+
autoApproveHostActions: false,
|
|
751
754
|
isolateClaudeConfig: false,
|
|
752
755
|
isolateCodexConfig: false,
|
|
753
756
|
isolateOpencodeConfig: false,
|
|
@@ -768,7 +771,8 @@ var BUILT_IN_DEFAULTS = {
|
|
|
768
771
|
bundleDepth: void 0,
|
|
769
772
|
vercelVcpus: 2,
|
|
770
773
|
vercelTimeoutMs: 27e5,
|
|
771
|
-
vercelNetworkPolicy: ""
|
|
774
|
+
vercelNetworkPolicy: "",
|
|
775
|
+
cpMaxBytes: 100 * 1024 * 1024
|
|
772
776
|
},
|
|
773
777
|
checkpoint: {
|
|
774
778
|
maxLayers: 3
|
|
@@ -824,7 +828,8 @@ var BUILT_IN_DEFAULTS = {
|
|
|
824
828
|
enabled: true,
|
|
825
829
|
maxConcurrent: 5,
|
|
826
830
|
maxWorking: 0,
|
|
827
|
-
idleGraceSeconds: 15
|
|
831
|
+
idleGraceSeconds: 15,
|
|
832
|
+
openIn: "none"
|
|
828
833
|
},
|
|
829
834
|
cloud: {
|
|
830
835
|
useCurrentBranch: false
|
|
@@ -942,6 +947,11 @@ var KEY_REGISTRY = [
|
|
|
942
947
|
type: "bool",
|
|
943
948
|
description: "Run the per-box Xvnc + noVNC stack."
|
|
944
949
|
},
|
|
950
|
+
{
|
|
951
|
+
key: "box.autoApproveHostActions",
|
|
952
|
+
type: "bool",
|
|
953
|
+
description: "Auto-approve host-action confirmations (git push, cp host<->box, gh PR writes, checkpoint) for this box without an interactive prompt. Off by default; intended for unattended orchestration of trusted boxes. Each auto-approval is recorded as a relay event (visible in `agentbox agent` / the dashboard)."
|
|
954
|
+
},
|
|
945
955
|
{
|
|
946
956
|
key: "box.isolateClaudeConfig",
|
|
947
957
|
type: "bool",
|
|
@@ -1040,6 +1050,12 @@ var KEY_REGISTRY = [
|
|
|
1040
1050
|
type: "int",
|
|
1041
1051
|
description: "Max session length (ms) for new --provider vercel boxes before the VM auto-snapshots; persistent mode auto-resumes on the next call. Default 2700000 (45 min, the Hobby ceiling). Vercel-only."
|
|
1042
1052
|
},
|
|
1053
|
+
{
|
|
1054
|
+
key: "box.cpMaxBytes",
|
|
1055
|
+
type: "int",
|
|
1056
|
+
description: "Max bytes a single host\u2192box copy may transfer after excludes, shared by `agentbox cp` (blocked with a size breakdown unless --yes) and each `carry:` entry (rejected at resolve time). Default 104857600 (100 MiB).",
|
|
1057
|
+
advanced: true
|
|
1058
|
+
},
|
|
1043
1059
|
{
|
|
1044
1060
|
key: "box.vercelNetworkPolicy",
|
|
1045
1061
|
type: "string",
|
|
@@ -1187,6 +1203,12 @@ var KEY_REGISTRY = [
|
|
|
1187
1203
|
type: "int",
|
|
1188
1204
|
description: "Seconds an agent must stay non-working before it frees its working slot (debounce against brief idle flaps between turns). Only used when queue.maxWorking > 0."
|
|
1189
1205
|
},
|
|
1206
|
+
{
|
|
1207
|
+
key: "queue.openIn",
|
|
1208
|
+
type: "enum",
|
|
1209
|
+
enumValues: ["none", "split", "window", "tab"],
|
|
1210
|
+
description: "When a background `-i` job finishes creating its box, where the host relay opens an attached terminal onto it: `none` (default \u2014 open nothing, just queue), `split`, `window`, or `tab`. Honored only when the submitting shell runs inside tmux, cmux, or iTerm2 (the targeting is captured at submit time). Under cmux, `split` splits the pane you submitted from (falling back to the parent workspace, then a new workspace), `tab` adds a tab in the parent workspace, and `window` opens a separate workspace; iTerm2 opens relative to the frontmost window. Unlike `attach.openIn` there is no `same` mode \u2014 the box is created asynchronously, so it is always a fresh terminal."
|
|
1211
|
+
},
|
|
1190
1212
|
{
|
|
1191
1213
|
key: "cloud.useCurrentBranch",
|
|
1192
1214
|
type: "bool",
|
|
@@ -1771,33 +1793,48 @@ async function touchProjectMeta(absPath) {
|
|
|
1771
1793
|
}
|
|
1772
1794
|
|
|
1773
1795
|
// ../../packages/sandbox-docker/dist/index.js
|
|
1796
|
+
import { spawnSync } from "child_process";
|
|
1797
|
+
import { mkdir as mkdir3, mkdtemp as mkdtemp2, readdir as readdir3, readFile as readFile42, realpath as realpath2, rm as rm2, stat as stat3, writeFile as writeFile22 } from "fs/promises";
|
|
1798
|
+
import { homedir as homedir3, tmpdir as tmpdir2 } from "os";
|
|
1799
|
+
import { isAbsolute as isAbsolute2, join as join4, relative as relative2 } from "path";
|
|
1800
|
+
import { setTimeout as delay } from "timers/promises";
|
|
1801
|
+
import { execa as execa6 } from "execa";
|
|
1802
|
+
import { execa as execa2 } from "execa";
|
|
1803
|
+
import { mkdir as mkdir4, readFile as readFile5, readdir as readdir4, stat as stat4 } from "fs/promises";
|
|
1804
|
+
import { createHash as createHash3 } from "crypto";
|
|
1805
|
+
import { homedir as homedir2 } from "os";
|
|
1806
|
+
import { join as join5 } from "path";
|
|
1807
|
+
import { execa as execa3 } from "execa";
|
|
1808
|
+
import { existsSync, mkdirSync, renameSync, statSync } from "fs";
|
|
1809
|
+
import { basename as basename2, dirname as dirname3, posix, resolve as resolve2 } from "path";
|
|
1810
|
+
import { execa as execa22 } from "execa";
|
|
1774
1811
|
import { copyFile, mkdtemp, readdir as readdir22, readFile as readFile32, rm as rm3, stat as stat22, writeFile as writeFile3 } from "fs/promises";
|
|
1775
1812
|
import { homedir as homedir22, tmpdir } from "os";
|
|
1776
|
-
import { basename as
|
|
1777
|
-
import { execa as
|
|
1813
|
+
import { basename as basename3, join as join32, relative } from "path";
|
|
1814
|
+
import { execa as execa5 } from "execa";
|
|
1778
1815
|
import { chmod, mkdir as mkdir22, readFile as readFile23 } from "fs/promises";
|
|
1779
|
-
import { basename as
|
|
1780
|
-
import { execa as
|
|
1816
|
+
import { basename as basename22, join as join22 } from "path";
|
|
1817
|
+
import { execa as execa4 } from "execa";
|
|
1781
1818
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
1782
1819
|
import { stat as stat42 } from "fs/promises";
|
|
1783
1820
|
import { homedir as homedir4 } from "os";
|
|
1784
1821
|
import { join as join52 } from "path";
|
|
1785
|
-
import { execa as
|
|
1822
|
+
import { execa as execa7 } from "execa";
|
|
1786
1823
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
1787
1824
|
import { stat as stat5 } from "fs/promises";
|
|
1788
1825
|
import { homedir as homedir5 } from "os";
|
|
1789
1826
|
import { join as join6 } from "path";
|
|
1790
|
-
import { execa as
|
|
1827
|
+
import { execa as execa8 } from "execa";
|
|
1791
1828
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
1792
1829
|
import { createHash as createHash22 } from "crypto";
|
|
1793
1830
|
import { readFile as readFile52 } from "fs/promises";
|
|
1794
1831
|
import { join as join7 } from "path";
|
|
1795
|
-
import { execa as
|
|
1796
|
-
import { existsSync } from "fs";
|
|
1832
|
+
import { execa as execa9 } from "execa";
|
|
1833
|
+
import { existsSync as existsSync2 } from "fs";
|
|
1797
1834
|
import { readFile as readFile6 } from "fs/promises";
|
|
1798
1835
|
import { homedir as homedir6 } from "os";
|
|
1799
1836
|
import { join as join8 } from "path";
|
|
1800
|
-
import { execa as
|
|
1837
|
+
import { execa as execa10 } from "execa";
|
|
1801
1838
|
|
|
1802
1839
|
// ../../packages/core/dist/index.js
|
|
1803
1840
|
import { randomBytes } from "crypto";
|
|
@@ -1862,25 +1899,25 @@ function generateBoxId() {
|
|
|
1862
1899
|
}
|
|
1863
1900
|
|
|
1864
1901
|
// ../../packages/sandbox-docker/dist/index.js
|
|
1865
|
-
import { execa as
|
|
1902
|
+
import { execa as execa11 } from "execa";
|
|
1866
1903
|
import { mkdir as mkdir42, readdir as readdir42, rm as rm32, stat as stat6 } from "fs/promises";
|
|
1867
1904
|
import { homedir as homedir7, platform } from "os";
|
|
1868
|
-
import { join as join9, resolve as
|
|
1905
|
+
import { join as join9, resolve as resolve22 } from "path";
|
|
1869
1906
|
import { mkdir as mkdir5, mkdtemp as mkdtemp3, readFile as readFile7, readdir as readdir5, rm as rm4, writeFile as writeFile32 } from "fs/promises";
|
|
1870
1907
|
import { homedir as homedir8, tmpdir as tmpdir3 } from "os";
|
|
1871
|
-
import { basename as
|
|
1872
|
-
import { execa as execa11 } from "execa";
|
|
1873
|
-
import { stat as stat7 } from "fs/promises";
|
|
1908
|
+
import { basename as basename4, join as join10 } from "path";
|
|
1874
1909
|
import { execa as execa12 } from "execa";
|
|
1910
|
+
import { stat as stat7 } from "fs/promises";
|
|
1875
1911
|
import { execa as execa13 } from "execa";
|
|
1912
|
+
import { execa as execa14 } from "execa";
|
|
1876
1913
|
import { spawn } from "child_process";
|
|
1877
1914
|
import { randomBytes as randomBytes22 } from "crypto";
|
|
1878
|
-
import { existsSync as
|
|
1915
|
+
import { existsSync as existsSync3, openSync } from "fs";
|
|
1879
1916
|
import { cp, mkdir as mkdir6, readFile as readFile8, readdir as readdir6, rename as rename3, rm as rm5, unlink as unlink2, writeFile as writeFile4 } from "fs/promises";
|
|
1880
1917
|
import { request as httpRequest } from "http";
|
|
1881
1918
|
import { createRequire } from "module";
|
|
1882
1919
|
import { homedir as homedir9 } from "os";
|
|
1883
|
-
import { dirname as
|
|
1920
|
+
import { dirname as dirname22, join as join11, resolve as resolve3, sep } from "path";
|
|
1884
1921
|
import { setTimeout as delay2 } from "timers/promises";
|
|
1885
1922
|
import { fileURLToPath } from "url";
|
|
1886
1923
|
|
|
@@ -2110,16 +2147,13 @@ function queueLogPath(id) {
|
|
|
2110
2147
|
}
|
|
2111
2148
|
|
|
2112
2149
|
// ../../packages/sandbox-docker/dist/index.js
|
|
2113
|
-
import { execa as
|
|
2150
|
+
import { execa as execa17 } from "execa";
|
|
2114
2151
|
import { readdir as readdir7, rm as rm6, stat as stat9 } from "fs/promises";
|
|
2115
2152
|
import { join as join14 } from "path";
|
|
2116
|
-
import { execa as
|
|
2153
|
+
import { execa as execa16 } from "execa";
|
|
2117
2154
|
import { join as join13 } from "path";
|
|
2118
2155
|
import { homedir as homedir11 } from "os";
|
|
2119
2156
|
import { join as join15 } from "path";
|
|
2120
|
-
import { execa as execa17 } from "execa";
|
|
2121
|
-
import { existsSync as existsSync3, mkdirSync, renameSync, statSync } from "fs";
|
|
2122
|
-
import { basename as basename5, dirname as dirname22, posix, resolve as resolve4 } from "path";
|
|
2123
2157
|
import { execa as execa18 } from "execa";
|
|
2124
2158
|
import { createHash as createHash32 } from "crypto";
|
|
2125
2159
|
import { copyFile as copyFile2, mkdir as mkdir8, mkdtemp as mkdtemp4, readdir as readdir8, readFile as readFile9, rm as rm7, stat as stat10 } from "fs/promises";
|
|
@@ -2520,11 +2554,144 @@ async function listAgentboxVolumes() {
|
|
|
2520
2554
|
if (result.exitCode !== 0) return [];
|
|
2521
2555
|
return (result.stdout ?? "").split("\n").map((s) => s.trim()).filter((s) => s.startsWith(AGENTBOX_PREFIX));
|
|
2522
2556
|
}
|
|
2557
|
+
function posixDirname(p) {
|
|
2558
|
+
return posix.dirname(p) || "/";
|
|
2559
|
+
}
|
|
2560
|
+
function asText(s) {
|
|
2561
|
+
if (s === void 0) return "";
|
|
2562
|
+
if (typeof s === "string") return s;
|
|
2563
|
+
return Buffer.from(s).toString("utf8");
|
|
2564
|
+
}
|
|
2565
|
+
function tarExcludeArgs(exclude) {
|
|
2566
|
+
return (exclude ?? []).map((p) => `--exclude=${p}`);
|
|
2567
|
+
}
|
|
2568
|
+
async function streamTarPipe(producerFile, producerArgs, consumerFile, consumerArgs, producerEnv) {
|
|
2569
|
+
const producer = execa22(producerFile, producerArgs, {
|
|
2570
|
+
reject: false,
|
|
2571
|
+
buffer: { stdout: false },
|
|
2572
|
+
...producerEnv ? { env: producerEnv } : {}
|
|
2573
|
+
});
|
|
2574
|
+
const consumer = execa22(consumerFile, consumerArgs, {
|
|
2575
|
+
reject: false,
|
|
2576
|
+
buffer: { stdout: false }
|
|
2577
|
+
});
|
|
2578
|
+
producer.stdout?.pipe(consumer.stdin);
|
|
2579
|
+
const [p, c] = await Promise.all([producer, consumer]);
|
|
2580
|
+
return [
|
|
2581
|
+
{ exitCode: p.exitCode, stderr: p.stderr },
|
|
2582
|
+
{ exitCode: c.exitCode, stderr: c.stderr }
|
|
2583
|
+
];
|
|
2584
|
+
}
|
|
2585
|
+
async function uploadToBox(box, hostSrc, boxDst, exclude) {
|
|
2586
|
+
const srcAbs = resolve2(hostSrc);
|
|
2587
|
+
if (!existsSync(srcAbs)) throw new Error(`source not found: ${hostSrc}`);
|
|
2588
|
+
const srcBasename = basename2(srcAbs);
|
|
2589
|
+
const srcParent = dirname3(srcAbs);
|
|
2590
|
+
let boxParent;
|
|
2591
|
+
let finalName;
|
|
2592
|
+
if (boxDst.endsWith("/")) {
|
|
2593
|
+
boxParent = boxDst.replace(/\/+$/, "") || "/";
|
|
2594
|
+
finalName = srcBasename;
|
|
2595
|
+
} else {
|
|
2596
|
+
const isDir2 = await execa22(
|
|
2597
|
+
"docker",
|
|
2598
|
+
["exec", box.container, "test", "-d", boxDst],
|
|
2599
|
+
{ reject: false }
|
|
2600
|
+
);
|
|
2601
|
+
if (isDir2.exitCode === 0) {
|
|
2602
|
+
boxParent = boxDst.replace(/\/+$/, "") || "/";
|
|
2603
|
+
finalName = srcBasename;
|
|
2604
|
+
} else {
|
|
2605
|
+
boxParent = posixDirname(boxDst);
|
|
2606
|
+
finalName = posix.basename(boxDst);
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
const finalPath = boxParent === "/" ? `/${finalName}` : `${boxParent}/${finalName}`;
|
|
2610
|
+
const mk = await execa22(
|
|
2611
|
+
"docker",
|
|
2612
|
+
["exec", "--user", "root", box.container, "mkdir", "-p", boxParent],
|
|
2613
|
+
{ reject: false }
|
|
2614
|
+
);
|
|
2615
|
+
if (mk.exitCode !== 0) {
|
|
2616
|
+
throw new Error(`mkdir -p ${boxParent} in box failed: ${asText(mk.stderr).slice(0, 300)}`);
|
|
2617
|
+
}
|
|
2618
|
+
const [packed, extracted] = await streamTarPipe(
|
|
2619
|
+
"tar",
|
|
2620
|
+
["-C", srcParent, "-cf", "-", ...tarExcludeArgs(exclude), srcBasename],
|
|
2621
|
+
"docker",
|
|
2622
|
+
["exec", "-i", "--user", "root", box.container, "tar", "-xf", "-", "-C", boxParent],
|
|
2623
|
+
{ ...process.env, COPYFILE_DISABLE: "1" }
|
|
2624
|
+
);
|
|
2625
|
+
if (packed.exitCode !== 0) {
|
|
2626
|
+
throw new Error(`tar pack failed: ${asText(packed.stderr).slice(0, 300)}`);
|
|
2627
|
+
}
|
|
2628
|
+
if (extracted.exitCode !== 0) {
|
|
2629
|
+
throw new Error(`tar extract in box failed: ${asText(extracted.stderr).slice(0, 300)}`);
|
|
2630
|
+
}
|
|
2631
|
+
if (finalName !== srcBasename) {
|
|
2632
|
+
const initial = boxParent === "/" ? `/${srcBasename}` : `${boxParent}/${srcBasename}`;
|
|
2633
|
+
const mv = await execa22(
|
|
2634
|
+
"docker",
|
|
2635
|
+
["exec", "--user", "root", box.container, "mv", initial, finalPath],
|
|
2636
|
+
{ reject: false }
|
|
2637
|
+
);
|
|
2638
|
+
if (mv.exitCode !== 0) {
|
|
2639
|
+
throw new Error(
|
|
2640
|
+
`rename ${initial} -> ${finalPath} in box failed: ${asText(mv.stderr).slice(0, 300)}`
|
|
2641
|
+
);
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
const chown = await execa22(
|
|
2645
|
+
"docker",
|
|
2646
|
+
["exec", "--user", "root", box.container, "chown", "-R", "1000:1000", finalPath],
|
|
2647
|
+
{ reject: false }
|
|
2648
|
+
);
|
|
2649
|
+
if (chown.exitCode !== 0) {
|
|
2650
|
+
return {
|
|
2651
|
+
finalPath,
|
|
2652
|
+
warn: `chown ${finalPath} to vscode (uid 1000) failed; ownership inside the box may be root.`
|
|
2653
|
+
};
|
|
2654
|
+
}
|
|
2655
|
+
return { finalPath };
|
|
2656
|
+
}
|
|
2657
|
+
async function downloadFromBox(box, boxSrc, hostDst, exclude) {
|
|
2658
|
+
const srcBasename = posix.basename(boxSrc);
|
|
2659
|
+
const srcParent = posixDirname(boxSrc);
|
|
2660
|
+
const dstAbs = resolve2(hostDst);
|
|
2661
|
+
let hostParent;
|
|
2662
|
+
let finalName;
|
|
2663
|
+
const dstExists = existsSync(dstAbs);
|
|
2664
|
+
if (hostDst.endsWith("/") || dstExists && statSync(dstAbs).isDirectory()) {
|
|
2665
|
+
hostParent = dstAbs;
|
|
2666
|
+
finalName = srcBasename;
|
|
2667
|
+
} else {
|
|
2668
|
+
hostParent = dirname3(dstAbs);
|
|
2669
|
+
finalName = basename2(dstAbs);
|
|
2670
|
+
}
|
|
2671
|
+
mkdirSync(hostParent, { recursive: true });
|
|
2672
|
+
const finalPath = posix.join(hostParent, finalName);
|
|
2673
|
+
const [packed, extracted] = await streamTarPipe(
|
|
2674
|
+
"docker",
|
|
2675
|
+
["exec", box.container, "tar", "-C", srcParent, "-cf", "-", ...tarExcludeArgs(exclude), srcBasename],
|
|
2676
|
+
"tar",
|
|
2677
|
+
["-xf", "-", "-C", hostParent]
|
|
2678
|
+
);
|
|
2679
|
+
if (packed.exitCode !== 0) {
|
|
2680
|
+
throw new Error(`tar pack in box failed: ${asText(packed.stderr).slice(0, 300)}`);
|
|
2681
|
+
}
|
|
2682
|
+
if (extracted.exitCode !== 0) {
|
|
2683
|
+
throw new Error(`tar extract on host failed: ${asText(extracted.stderr).slice(0, 300)}`);
|
|
2684
|
+
}
|
|
2685
|
+
if (finalName !== srcBasename) {
|
|
2686
|
+
renameSync(posix.join(hostParent, srcBasename), finalPath);
|
|
2687
|
+
}
|
|
2688
|
+
return { finalPath };
|
|
2689
|
+
}
|
|
2523
2690
|
var CONTAINER_EXPORT_MERGED = "/host-export";
|
|
2524
2691
|
var cachedEngine = null;
|
|
2525
2692
|
async function detectEngine() {
|
|
2526
2693
|
if (cachedEngine !== null) return cachedEngine;
|
|
2527
|
-
const result = await
|
|
2694
|
+
const result = await execa3("docker", ["info", "--format", "{{.OperatingSystem}}"], {
|
|
2528
2695
|
reject: false
|
|
2529
2696
|
});
|
|
2530
2697
|
const os = (result.stdout ?? "").trim().toLowerCase();
|
|
@@ -2537,7 +2704,7 @@ function setEngineOverride(engine) {
|
|
|
2537
2704
|
cachedEngine = engine;
|
|
2538
2705
|
}
|
|
2539
2706
|
async function getDockerContext() {
|
|
2540
|
-
const result = await
|
|
2707
|
+
const result = await execa3("docker", ["context", "show"], { reject: false });
|
|
2541
2708
|
if (result.exitCode !== 0) return void 0;
|
|
2542
2709
|
const ctx = (result.stdout ?? "").trim();
|
|
2543
2710
|
return ctx.length > 0 ? ctx : void 0;
|
|
@@ -2597,7 +2764,7 @@ async function refreshExport(record, opts = {}) {
|
|
|
2597
2764
|
return { hostPath: paths.mergedExport, copied: true, usedFallback: false };
|
|
2598
2765
|
}
|
|
2599
2766
|
const excludes = excludeNodeModules ? ["--exclude=node_modules"] : [];
|
|
2600
|
-
const result = await
|
|
2767
|
+
const result = await execa3(
|
|
2601
2768
|
"docker",
|
|
2602
2769
|
["exec", "--user", "root", record.container, "tar", "-cf", "-", ...excludes, "-C", "/workspace", "."],
|
|
2603
2770
|
{ reject: false, encoding: "buffer" }
|
|
@@ -2609,7 +2776,7 @@ async function refreshExport(record, opts = {}) {
|
|
|
2609
2776
|
typeof result.stderr === "string" ? result.stderr : result.stderr.toString("utf8")
|
|
2610
2777
|
);
|
|
2611
2778
|
}
|
|
2612
|
-
const extract = await
|
|
2779
|
+
const extract = await execa3("tar", ["-xf", "-", "-C", paths.mergedExport], {
|
|
2613
2780
|
input: result.stdout,
|
|
2614
2781
|
reject: false
|
|
2615
2782
|
});
|
|
@@ -2704,7 +2871,7 @@ function buildHostEnvFindArgs(patterns) {
|
|
|
2704
2871
|
async function copyHostEnvFilesToBox(opts) {
|
|
2705
2872
|
const log = opts.onLog ?? (() => {
|
|
2706
2873
|
});
|
|
2707
|
-
const found = await
|
|
2874
|
+
const found = await execa3("find", buildHostEnvFindArgs(opts.patterns).slice(1), {
|
|
2708
2875
|
cwd: opts.workspaceDir,
|
|
2709
2876
|
reject: false
|
|
2710
2877
|
});
|
|
@@ -2714,7 +2881,7 @@ async function copyHostEnvFilesToBox(opts) {
|
|
|
2714
2881
|
}
|
|
2715
2882
|
const list = String(found.stdout).split("\0").filter((p) => p.length > 0);
|
|
2716
2883
|
if (list.length === 0) return { copied: 0 };
|
|
2717
|
-
const packed = await
|
|
2884
|
+
const packed = await execa3("tar", ["-C", opts.workspaceDir, "--null", "-T", "-", "-cf", "-"], {
|
|
2718
2885
|
input: list.join("\0"),
|
|
2719
2886
|
encoding: "buffer",
|
|
2720
2887
|
reject: false
|
|
@@ -2723,7 +2890,7 @@ async function copyHostEnvFilesToBox(opts) {
|
|
|
2723
2890
|
log(`warning: env-file tar pack failed: ${String(packed.stderr).slice(0, 300)}`);
|
|
2724
2891
|
return { copied: 0 };
|
|
2725
2892
|
}
|
|
2726
|
-
const extract = await
|
|
2893
|
+
const extract = await execa3(
|
|
2727
2894
|
"docker",
|
|
2728
2895
|
["exec", "-i", "--user", "1000:1000", opts.container, "tar", "-xf", "-", "-C", "/workspace"],
|
|
2729
2896
|
{ input: packed.stdout, reject: false }
|
|
@@ -2736,7 +2903,7 @@ async function copyHostEnvFilesToBox(opts) {
|
|
|
2736
2903
|
}
|
|
2737
2904
|
async function scanHostEnvFiles(workspaceDir, patterns) {
|
|
2738
2905
|
if (patterns.length === 0) return [];
|
|
2739
|
-
const found = await
|
|
2906
|
+
const found = await execa3("find", buildHostEnvFindArgs(patterns).slice(1), {
|
|
2740
2907
|
cwd: workspaceDir,
|
|
2741
2908
|
reject: false
|
|
2742
2909
|
});
|
|
@@ -2748,7 +2915,7 @@ async function copyHostFilesToBox(opts) {
|
|
|
2748
2915
|
});
|
|
2749
2916
|
const list = opts.files.map((p) => p.replace(/^\.\//, "")).filter((p) => p.length > 0);
|
|
2750
2917
|
if (list.length === 0) return { copied: 0 };
|
|
2751
|
-
const packed = await
|
|
2918
|
+
const packed = await execa3("tar", ["-C", opts.workspaceDir, "--null", "-T", "-", "-cf", "-"], {
|
|
2752
2919
|
input: list.join("\0"),
|
|
2753
2920
|
encoding: "buffer",
|
|
2754
2921
|
reject: false
|
|
@@ -2757,7 +2924,7 @@ async function copyHostFilesToBox(opts) {
|
|
|
2757
2924
|
log(`warning: env-file tar pack failed: ${String(packed.stderr).slice(0, 300)}`);
|
|
2758
2925
|
return { copied: 0 };
|
|
2759
2926
|
}
|
|
2760
|
-
const extract = await
|
|
2927
|
+
const extract = await execa3(
|
|
2761
2928
|
"docker",
|
|
2762
2929
|
["exec", "-i", "--user", "1000:1000", opts.container, "tar", "-xf", "-", "-C", "/workspace"],
|
|
2763
2930
|
{ input: packed.stdout, reject: false }
|
|
@@ -2831,7 +2998,7 @@ async function pullToHost(record, opts = {}) {
|
|
|
2831
2998
|
}
|
|
2832
2999
|
const src = `${scratchDir}/`;
|
|
2833
3000
|
const dst = `${record.workspacePath}/`;
|
|
2834
|
-
const dry = await
|
|
3001
|
+
const dry = await execa3("rsync", [...baseArgs, "--dry-run", "-i", src, dst], {
|
|
2835
3002
|
reject: false,
|
|
2836
3003
|
input: fileList !== null ? fileList : void 0
|
|
2837
3004
|
});
|
|
@@ -2842,7 +3009,7 @@ async function pullToHost(record, opts = {}) {
|
|
|
2842
3009
|
if (opts.dryRun) {
|
|
2843
3010
|
return { hostPath: record.workspacePath, changes, applied: false, usedGitignore };
|
|
2844
3011
|
}
|
|
2845
|
-
const real = await
|
|
3012
|
+
const real = await execa3("rsync", [...baseArgs, src, dst], {
|
|
2846
3013
|
reject: false,
|
|
2847
3014
|
input: fileList !== null ? fileList : void 0
|
|
2848
3015
|
});
|
|
@@ -2867,7 +3034,7 @@ async function openInFinder(record, opts) {
|
|
|
2867
3034
|
usedFallback = refreshed.usedFallback;
|
|
2868
3035
|
}
|
|
2869
3036
|
if (!opts.noOpen) {
|
|
2870
|
-
const opened = await
|
|
3037
|
+
const opened = await execa3(hostOpenCommand(), [hostPath], { reject: false });
|
|
2871
3038
|
if (opened.exitCode !== 0) {
|
|
2872
3039
|
throw new ExportError(`open ${hostPath} failed`, opened.stdout, opened.stderr);
|
|
2873
3040
|
}
|
|
@@ -2890,12 +3057,14 @@ async function carrySourceHash(entry) {
|
|
|
2890
3057
|
if (entry.kind === "file") {
|
|
2891
3058
|
return createHash3("sha256").update(await readFile5(entry.absSrc)).digest("hex");
|
|
2892
3059
|
}
|
|
3060
|
+
const exclude = entry.exclude ?? [];
|
|
2893
3061
|
const h = createHash3("sha256");
|
|
2894
3062
|
const walk = async (dir, rel) => {
|
|
2895
3063
|
const names = (await readdir4(dir)).sort();
|
|
2896
3064
|
for (const name of names) {
|
|
2897
|
-
const abs = join5(dir, name);
|
|
2898
3065
|
const relPath = rel ? `${rel}/${name}` : name;
|
|
3066
|
+
if (carryRelExcluded(relPath, exclude)) continue;
|
|
3067
|
+
const abs = join5(dir, name);
|
|
2899
3068
|
const st = await stat4(abs);
|
|
2900
3069
|
if (st.isDirectory()) {
|
|
2901
3070
|
h.update(`d\0${relPath}
|
|
@@ -2914,6 +3083,24 @@ async function carrySourceHash(entry) {
|
|
|
2914
3083
|
return void 0;
|
|
2915
3084
|
}
|
|
2916
3085
|
}
|
|
3086
|
+
function carryRelExcluded(relPath, patterns) {
|
|
3087
|
+
if (patterns.length === 0) return false;
|
|
3088
|
+
const segs = relPath.split("/");
|
|
3089
|
+
for (const p of patterns) {
|
|
3090
|
+
const isGlob = p.includes("*") || p.includes("?");
|
|
3091
|
+
if (!isGlob) {
|
|
3092
|
+
if (segs.includes(p)) return true;
|
|
3093
|
+
} else if (p.startsWith("*/") && !/[*?/]/.test(p.slice(2))) {
|
|
3094
|
+
if (segs.includes(p.slice(2))) return true;
|
|
3095
|
+
} else {
|
|
3096
|
+
const re = new RegExp(
|
|
3097
|
+
`^${p.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".")}$`
|
|
3098
|
+
);
|
|
3099
|
+
if (re.test(relPath)) return true;
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
return false;
|
|
3103
|
+
}
|
|
2917
3104
|
async function copyCarryPathsToBox(opts) {
|
|
2918
3105
|
const log = opts.onLog ?? (() => {
|
|
2919
3106
|
});
|
|
@@ -2949,7 +3136,7 @@ async function copyOneEntry(container, entry) {
|
|
|
2949
3136
|
const boxDest = entry.absDest.startsWith("~/") ? `${BOX_HOME}/${entry.absDest.slice(2)}` : entry.absDest;
|
|
2950
3137
|
const boxDestParent = boxDest.endsWith("/") ? boxDest.slice(0, -1) : boxDest;
|
|
2951
3138
|
const parentDir = entry.kind === "dir" ? boxDestParent : dirnameUnix(boxDestParent);
|
|
2952
|
-
const mkdir9 = await
|
|
3139
|
+
const mkdir9 = await execa3(
|
|
2953
3140
|
"docker",
|
|
2954
3141
|
["exec", "--user", "0:0", container, "mkdir", "-p", parentDir],
|
|
2955
3142
|
{ reject: false }
|
|
@@ -2958,7 +3145,7 @@ async function copyOneEntry(container, entry) {
|
|
|
2958
3145
|
throw new Error(`mkdir -p ${parentDir} failed: ${String(mkdir9.stderr).slice(0, 300)}`);
|
|
2959
3146
|
}
|
|
2960
3147
|
if (entry.kind === "file") {
|
|
2961
|
-
const cp2 = await
|
|
3148
|
+
const cp2 = await execa3(
|
|
2962
3149
|
"docker",
|
|
2963
3150
|
["cp", entry.absSrc, `${container}:${boxDest}`],
|
|
2964
3151
|
{ reject: false }
|
|
@@ -2967,15 +3154,10 @@ async function copyOneEntry(container, entry) {
|
|
|
2967
3154
|
throw new Error(`docker cp failed: ${String(cp2.stderr).slice(0, 300)}`);
|
|
2968
3155
|
}
|
|
2969
3156
|
} else {
|
|
2970
|
-
const
|
|
3157
|
+
const excludeArgs = (entry.exclude ?? []).map((p) => `--exclude=${p}`);
|
|
3158
|
+
const [packed, extract] = await streamTarPipe(
|
|
2971
3159
|
"tar",
|
|
2972
|
-
["-C", entry.absSrc, "-cf", "-", "."],
|
|
2973
|
-
{ encoding: "buffer", reject: false }
|
|
2974
|
-
);
|
|
2975
|
-
if (packed.exitCode !== 0) {
|
|
2976
|
-
throw new Error(`tar pack failed: ${String(packed.stderr).slice(0, 300)}`);
|
|
2977
|
-
}
|
|
2978
|
-
const extract = await execa22(
|
|
3160
|
+
["-C", entry.absSrc, "-cf", "-", ...excludeArgs, "."],
|
|
2979
3161
|
"docker",
|
|
2980
3162
|
[
|
|
2981
3163
|
"exec",
|
|
@@ -2991,16 +3173,18 @@ async function copyOneEntry(container, entry) {
|
|
|
2991
3173
|
"--no-same-permissions",
|
|
2992
3174
|
"--no-same-owner",
|
|
2993
3175
|
"-m"
|
|
2994
|
-
]
|
|
2995
|
-
{ input: packed.stdout, reject: false }
|
|
3176
|
+
]
|
|
2996
3177
|
);
|
|
3178
|
+
if (packed.exitCode !== 0) {
|
|
3179
|
+
throw new Error(`tar pack failed: ${String(packed.stderr).slice(0, 300)}`);
|
|
3180
|
+
}
|
|
2997
3181
|
if (extract.exitCode !== 0) {
|
|
2998
3182
|
throw new Error(`tar extract failed: ${String(extract.stderr).slice(0, 300)}`);
|
|
2999
3183
|
}
|
|
3000
3184
|
}
|
|
3001
3185
|
if (entry.mode !== void 0) {
|
|
3002
3186
|
const modeStr = entry.mode.toString(8).padStart(4, "0");
|
|
3003
|
-
const chmod2 = await
|
|
3187
|
+
const chmod2 = await execa3(
|
|
3004
3188
|
"docker",
|
|
3005
3189
|
["exec", "--user", "0:0", container, "chmod", "-R", modeStr, boxDest],
|
|
3006
3190
|
{ reject: false }
|
|
@@ -3010,7 +3194,7 @@ async function copyOneEntry(container, entry) {
|
|
|
3010
3194
|
}
|
|
3011
3195
|
}
|
|
3012
3196
|
const uid = entry.user ?? 1e3;
|
|
3013
|
-
const chown = await
|
|
3197
|
+
const chown = await execa3(
|
|
3014
3198
|
"docker",
|
|
3015
3199
|
["exec", "--user", "0:0", container, "chown", "-R", `${String(uid)}:${String(uid)}`, boxDest],
|
|
3016
3200
|
{ reject: false }
|
|
@@ -3021,7 +3205,7 @@ async function copyOneEntry(container, entry) {
|
|
|
3021
3205
|
if (boxDest.startsWith(BOX_HOME + "/") && dirnameUnix(boxDest) !== BOX_HOME) {
|
|
3022
3206
|
const safeDest = boxDest.replace(/'/g, `'\\''`);
|
|
3023
3207
|
const script = `set -e; parent="$(dirname '${safeDest}')"; while [ "$parent" != "${BOX_HOME}" ] && [ "$parent" != "/" ]; do chown ${String(uid)}:${String(uid)} "$parent"; parent="$(dirname "$parent")"; done`;
|
|
3024
|
-
const chownParents = await
|
|
3208
|
+
const chownParents = await execa3(
|
|
3025
3209
|
"docker",
|
|
3026
3210
|
["exec", "--user", "0:0", container, "bash", "-c", script],
|
|
3027
3211
|
{ reject: false }
|
|
@@ -3069,7 +3253,7 @@ async function extractVolumeAuthToBackup(opts) {
|
|
|
3069
3253
|
try {
|
|
3070
3254
|
await mkdir22(STATE_DIR, { recursive: true });
|
|
3071
3255
|
const script = 'COPIED=no; if [ -s /dst/auth.json ]; then cp -a /dst/auth.json "/host-state/$DEST" && COPIED=yes; fi; echo "COPIED=$COPIED"';
|
|
3072
|
-
const { stdout } = await
|
|
3256
|
+
const { stdout } = await execa4("docker", [
|
|
3073
3257
|
"run",
|
|
3074
3258
|
"--rm",
|
|
3075
3259
|
"--user",
|
|
@@ -3081,7 +3265,7 @@ async function extractVolumeAuthToBackup(opts) {
|
|
|
3081
3265
|
"-e",
|
|
3082
3266
|
// Pass the destination filename via env so the path isn't interpolated
|
|
3083
3267
|
// into the script string (keeps the docker arg list static + injection-safe).
|
|
3084
|
-
`DEST=${
|
|
3268
|
+
`DEST=${basename22(opts.backupFile)}`,
|
|
3085
3269
|
opts.image,
|
|
3086
3270
|
"sh",
|
|
3087
3271
|
"-c",
|
|
@@ -3133,7 +3317,7 @@ echo "EXTRACTED=$EXTRACTED SEEDED=$SEEDED VOLREAL=$VOL_REAL"
|
|
|
3133
3317
|
async function syncClaudeCredentials(spec, opts) {
|
|
3134
3318
|
try {
|
|
3135
3319
|
await mkdir22(STATE_DIR, { recursive: true });
|
|
3136
|
-
const { stdout } = await
|
|
3320
|
+
const { stdout } = await execa4("docker", [
|
|
3137
3321
|
"run",
|
|
3138
3322
|
"--rm",
|
|
3139
3323
|
"--user",
|
|
@@ -3201,8 +3385,8 @@ function emptyResult(warnings = []) {
|
|
|
3201
3385
|
}, warnings };
|
|
3202
3386
|
}
|
|
3203
3387
|
async function tarballFromDir(stageDir, agent) {
|
|
3204
|
-
const tarballPath = join32(tmpdir(), `agentbox-${agent}-${
|
|
3205
|
-
await
|
|
3388
|
+
const tarballPath = join32(tmpdir(), `agentbox-${agent}-${basename3(stageDir)}.tar.gz`);
|
|
3389
|
+
await execa5("tar", ["-czf", tarballPath, "-C", stageDir, "."], {
|
|
3206
3390
|
env: { ...process.env, COPYFILE_DISABLE: "1" }
|
|
3207
3391
|
});
|
|
3208
3392
|
return tarballPath;
|
|
@@ -3347,7 +3531,7 @@ async function stageClaudeStaticForUpload(opts = {}) {
|
|
|
3347
3531
|
...CLAUDE_RUNTIME_EXCLUDES.map((p) => `--exclude=${p}`),
|
|
3348
3532
|
...broken.map((r) => `--exclude=/${r}`)
|
|
3349
3533
|
];
|
|
3350
|
-
await
|
|
3534
|
+
await execa5("rsync", [
|
|
3351
3535
|
"-a",
|
|
3352
3536
|
"--copy-unsafe-links",
|
|
3353
3537
|
...excludes,
|
|
@@ -3436,7 +3620,7 @@ async function stageCodexStaticForUpload(opts = {}) {
|
|
|
3436
3620
|
let tarballPath = null;
|
|
3437
3621
|
try {
|
|
3438
3622
|
const codexBroken = await findBrokenSymlinks(hostCodex);
|
|
3439
|
-
await
|
|
3623
|
+
await execa5("rsync", [
|
|
3440
3624
|
"-a",
|
|
3441
3625
|
"-L",
|
|
3442
3626
|
...codexBroken.map((r) => `--exclude=/${r}`),
|
|
@@ -3492,7 +3676,7 @@ async function stageOpencodeStaticForUpload(opts = {}) {
|
|
|
3492
3676
|
try {
|
|
3493
3677
|
if (hasData) {
|
|
3494
3678
|
const dataBroken = await findBrokenSymlinks(hostData);
|
|
3495
|
-
await
|
|
3679
|
+
await execa5("rsync", [
|
|
3496
3680
|
"-a",
|
|
3497
3681
|
"-L",
|
|
3498
3682
|
...dataBroken.map((r) => `--exclude=/${r}`),
|
|
@@ -3505,7 +3689,7 @@ async function stageOpencodeStaticForUpload(opts = {}) {
|
|
|
3505
3689
|
if (hasConfig) {
|
|
3506
3690
|
const configStage = join32(stageDir, "config");
|
|
3507
3691
|
const cfgBroken = await findBrokenSymlinks(hostConfig);
|
|
3508
|
-
await
|
|
3692
|
+
await execa5("rsync", [
|
|
3509
3693
|
"-a",
|
|
3510
3694
|
"-L",
|
|
3511
3695
|
...cfgBroken.map((r) => `--exclude=/${r}`),
|
|
@@ -3563,7 +3747,7 @@ async function pathExists2(p) {
|
|
|
3563
3747
|
}
|
|
3564
3748
|
}
|
|
3565
3749
|
async function volumeHasClaudeJson(volume, image) {
|
|
3566
|
-
const res = await
|
|
3750
|
+
const res = await execa6(
|
|
3567
3751
|
"docker",
|
|
3568
3752
|
["run", "--rm", "-v", `${volume}:/dst`, image, "sh", "-c", "test -e /dst/_claude.json"],
|
|
3569
3753
|
{ reject: false }
|
|
@@ -3733,7 +3917,7 @@ async function ensureClaudeVolume(spec, opts) {
|
|
|
3733
3917
|
// linux/amd64 node_modules on the next `agentbox claude`.
|
|
3734
3918
|
`{ [ ! -f /dst/.agentbox-cleaned-nm-v1 ] && find /dst -name node_modules -type d -prune -exec rm -rf {} + && touch /dst/.agentbox-cleaned-nm-v1; true; } && rsync ${rsyncFlags} /src-claude/ /dst/ && { [ -f /src-claude-json ] && cp -a /src-claude-json /dst/_claude.json; true; } && { [ -f /src-filter/settings.json ] && cp -a /src-filter/settings.json /dst/settings.json; true; } && { [ -f /src-filter/_claude.json ] && cp -a /src-filter/_claude.json /dst/_claude.json; true; } && { [ -d /dst/plugins ] && [ -n "$HOST_HOME" ] && find /dst/plugins -maxdepth 1 -type f -name "*.json" -exec sed -i "s|$HOST_HOME/.claude/plugins/|/home/vscode/.claude/plugins/|g" {} +; true; }` + memoryRekeyStep + " && chown -R 1000:1000 /dst"
|
|
3735
3919
|
);
|
|
3736
|
-
await
|
|
3920
|
+
await execa6("docker", args);
|
|
3737
3921
|
} finally {
|
|
3738
3922
|
await rm2(filterDir, { recursive: true, force: true });
|
|
3739
3923
|
}
|
|
@@ -3748,7 +3932,7 @@ async function ensureClaudeVolume(spec, opts) {
|
|
|
3748
3932
|
}
|
|
3749
3933
|
async function seedSetupSkillIntoVolume(volume, image) {
|
|
3750
3934
|
try {
|
|
3751
|
-
const { stdout } = await
|
|
3935
|
+
const { stdout } = await execa6("docker", [
|
|
3752
3936
|
"run",
|
|
3753
3937
|
"--rm",
|
|
3754
3938
|
"--user",
|
|
@@ -3913,7 +4097,7 @@ async function resolveClaudeCacheLiveOnHost(volume) {
|
|
|
3913
4097
|
return orbstackVolumePath(volume, "plugins", "cache");
|
|
3914
4098
|
}
|
|
3915
4099
|
async function readBoxReferencedPluginKeys(container) {
|
|
3916
|
-
const res = await
|
|
4100
|
+
const res = await execa6(
|
|
3917
4101
|
"docker",
|
|
3918
4102
|
[
|
|
3919
4103
|
"exec",
|
|
@@ -4031,7 +4215,7 @@ while IFS= read -r dir; do
|
|
|
4031
4215
|
done < "$WORK/dirs"
|
|
4032
4216
|
rm -rf "$WORK"
|
|
4033
4217
|
`;
|
|
4034
|
-
const result = await
|
|
4218
|
+
const result = await execa6(
|
|
4035
4219
|
"docker",
|
|
4036
4220
|
["exec", "--user", CONTAINER_USER, container, "sh", "-c", script],
|
|
4037
4221
|
{ reject: false }
|
|
@@ -4092,7 +4276,7 @@ async function startClaudeSession(opts) {
|
|
|
4092
4276
|
const v = process.env[k];
|
|
4093
4277
|
if (typeof v === "string" && v.length > 0) envFlags.push("-e", `${k}=${v}`);
|
|
4094
4278
|
}
|
|
4095
|
-
const result = await
|
|
4279
|
+
const result = await execa6(
|
|
4096
4280
|
"docker",
|
|
4097
4281
|
[
|
|
4098
4282
|
"exec",
|
|
@@ -4183,7 +4367,7 @@ function buildDashboardAttachArgv(container, sessionName) {
|
|
|
4183
4367
|
async function waitForTmuxPaneContent(container, sessionName, timeoutMs = 2e4) {
|
|
4184
4368
|
const deadline = Date.now() + timeoutMs;
|
|
4185
4369
|
while (Date.now() < deadline) {
|
|
4186
|
-
const res = await
|
|
4370
|
+
const res = await execa6(
|
|
4187
4371
|
"docker",
|
|
4188
4372
|
["exec", "--user", CONTAINER_USER, container, "tmux", "capture-pane", "-p", "-t", sessionName],
|
|
4189
4373
|
{ reject: false }
|
|
@@ -4251,7 +4435,7 @@ async function warmUpClaudeCredentials(volume, image, opts = {}) {
|
|
|
4251
4435
|
const SLEEP_MS = 5e3;
|
|
4252
4436
|
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
4253
4437
|
opts.onProgress?.(`checking credentials... ${attempt}/${MAX_ATTEMPTS}`);
|
|
4254
|
-
const res = await
|
|
4438
|
+
const res = await execa6(
|
|
4255
4439
|
"docker",
|
|
4256
4440
|
[
|
|
4257
4441
|
"run",
|
|
@@ -4293,7 +4477,7 @@ function attachClaudeSession(container, sessionName, reattachRef) {
|
|
|
4293
4477
|
}
|
|
4294
4478
|
async function claudeSessionInfo(container, sessionName) {
|
|
4295
4479
|
const name = sessionName ?? DEFAULT_CLAUDE_SESSION;
|
|
4296
|
-
const has = await
|
|
4480
|
+
const has = await execa6(
|
|
4297
4481
|
"docker",
|
|
4298
4482
|
["exec", "--user", CONTAINER_USER, container, "tmux", "has-session", "-t", name],
|
|
4299
4483
|
{ reject: false }
|
|
@@ -4301,7 +4485,7 @@ async function claudeSessionInfo(container, sessionName) {
|
|
|
4301
4485
|
if (has.exitCode !== 0) {
|
|
4302
4486
|
return { running: false, sessionName: name, startedAt: null };
|
|
4303
4487
|
}
|
|
4304
|
-
const ts = await
|
|
4488
|
+
const ts = await execa6(
|
|
4305
4489
|
"docker",
|
|
4306
4490
|
[
|
|
4307
4491
|
"exec",
|
|
@@ -4367,7 +4551,7 @@ async function pullClaudeExtras(spec, opts) {
|
|
|
4367
4551
|
' printf "\\n";',
|
|
4368
4552
|
"done"
|
|
4369
4553
|
].join(" ");
|
|
4370
|
-
const inv = await
|
|
4554
|
+
const inv = await execa6(
|
|
4371
4555
|
"docker",
|
|
4372
4556
|
["run", "--rm", "--user", "0", "-v", `${spec.volume}:/src:ro`, opts.image, "sh", "-c", inventoryScript],
|
|
4373
4557
|
{ reject: false }
|
|
@@ -4440,7 +4624,7 @@ async function pullClaudeExtras(spec, opts) {
|
|
|
4440
4624
|
const parent = dest.slice(0, dest.lastIndexOf("/"));
|
|
4441
4625
|
return `mkdir -p '${parent}' && rsync -a --ignore-existing --exclude=node_modules '${src}/' '${dest}/'`;
|
|
4442
4626
|
});
|
|
4443
|
-
const apply = await
|
|
4627
|
+
const apply = await execa6(
|
|
4444
4628
|
"docker",
|
|
4445
4629
|
[
|
|
4446
4630
|
"run",
|
|
@@ -4513,7 +4697,7 @@ async function ensureCodexVolume(spec, opts) {
|
|
|
4513
4697
|
const hostCodex = join52(homedir4(), ".codex");
|
|
4514
4698
|
const willSync = opts.syncFromHost && await pathExists3(hostCodex);
|
|
4515
4699
|
if (willSync) {
|
|
4516
|
-
await
|
|
4700
|
+
await execa7("docker", [
|
|
4517
4701
|
"run",
|
|
4518
4702
|
"--rm",
|
|
4519
4703
|
"--user",
|
|
@@ -4531,7 +4715,7 @@ async function ensureCodexVolume(spec, opts) {
|
|
|
4531
4715
|
]);
|
|
4532
4716
|
return { created, synced: true };
|
|
4533
4717
|
}
|
|
4534
|
-
await
|
|
4718
|
+
await execa7(
|
|
4535
4719
|
"docker",
|
|
4536
4720
|
[
|
|
4537
4721
|
"run",
|
|
@@ -4551,7 +4735,7 @@ async function ensureCodexVolume(spec, opts) {
|
|
|
4551
4735
|
}
|
|
4552
4736
|
async function seedCodexHooks(volume, image) {
|
|
4553
4737
|
try {
|
|
4554
|
-
const { stdout } = await
|
|
4738
|
+
const { stdout } = await execa7("docker", [
|
|
4555
4739
|
"run",
|
|
4556
4740
|
"--rm",
|
|
4557
4741
|
"--user",
|
|
@@ -4588,14 +4772,14 @@ var CodexSessionError = class extends Error {
|
|
|
4588
4772
|
}
|
|
4589
4773
|
};
|
|
4590
4774
|
async function ensureCodexInstalled(container, opts = {}) {
|
|
4591
|
-
const probe = await
|
|
4775
|
+
const probe = await execa7(
|
|
4592
4776
|
"docker",
|
|
4593
4777
|
["exec", "--user", CONTAINER_USER, container, "sh", "-c", "command -v codex"],
|
|
4594
4778
|
{ reject: false }
|
|
4595
4779
|
);
|
|
4596
4780
|
if (probe.exitCode === 0) return { installed: false };
|
|
4597
4781
|
opts.onProgress?.("installing codex (absent from this box image)");
|
|
4598
|
-
const install = await
|
|
4782
|
+
const install = await execa7(
|
|
4599
4783
|
"docker",
|
|
4600
4784
|
["exec", "--user", "root", container, "bash", "-lc", "npm install -g @openai/codex 2>&1"],
|
|
4601
4785
|
{ reject: false }
|
|
@@ -4618,7 +4802,7 @@ async function startCodexSession(opts) {
|
|
|
4618
4802
|
const v = process.env[k];
|
|
4619
4803
|
if (typeof v === "string" && v.length > 0) envFlags.push("-e", `${k}=${v}`);
|
|
4620
4804
|
}
|
|
4621
|
-
const result = await
|
|
4805
|
+
const result = await execa7(
|
|
4622
4806
|
"docker",
|
|
4623
4807
|
[
|
|
4624
4808
|
"exec",
|
|
@@ -4700,7 +4884,7 @@ function runInteractiveCodexLogin(dockerArgv) {
|
|
|
4700
4884
|
return { exitCode: child.status ?? 1 };
|
|
4701
4885
|
}
|
|
4702
4886
|
async function volumeHasCodexAuth(volume, image) {
|
|
4703
|
-
const res = await
|
|
4887
|
+
const res = await execa7(
|
|
4704
4888
|
"docker",
|
|
4705
4889
|
["run", "--rm", "-v", `${volume}:/dst`, image, "sh", "-c", "test -e /dst/auth.json"],
|
|
4706
4890
|
{ reject: false }
|
|
@@ -4709,7 +4893,7 @@ async function volumeHasCodexAuth(volume, image) {
|
|
|
4709
4893
|
}
|
|
4710
4894
|
async function codexSessionInfo(container, sessionName) {
|
|
4711
4895
|
const name = sessionName ?? DEFAULT_CODEX_SESSION;
|
|
4712
|
-
const has = await
|
|
4896
|
+
const has = await execa7(
|
|
4713
4897
|
"docker",
|
|
4714
4898
|
["exec", "--user", CONTAINER_USER, container, "tmux", "has-session", "-t", name],
|
|
4715
4899
|
{ reject: false }
|
|
@@ -4717,7 +4901,7 @@ async function codexSessionInfo(container, sessionName) {
|
|
|
4717
4901
|
if (has.exitCode !== 0) {
|
|
4718
4902
|
return { running: false, sessionName: name, startedAt: null };
|
|
4719
4903
|
}
|
|
4720
|
-
const ts = await
|
|
4904
|
+
const ts = await execa7(
|
|
4721
4905
|
"docker",
|
|
4722
4906
|
[
|
|
4723
4907
|
"exec",
|
|
@@ -4743,7 +4927,7 @@ async function codexSessionInfo(container, sessionName) {
|
|
|
4743
4927
|
var CODEX_PULL_ITEMS = ["config.toml", "auth.json", "prompts"];
|
|
4744
4928
|
async function pullCodexConfig(spec, opts) {
|
|
4745
4929
|
const hostCodex = join52(homedir4(), ".codex");
|
|
4746
|
-
const inv = await
|
|
4930
|
+
const inv = await execa7(
|
|
4747
4931
|
"docker",
|
|
4748
4932
|
[
|
|
4749
4933
|
"run",
|
|
@@ -4777,7 +4961,7 @@ async function pullCodexConfig(spec, opts) {
|
|
|
4777
4961
|
const uid = process.getuid?.() ?? 0;
|
|
4778
4962
|
const gid = process.getgid?.() ?? 0;
|
|
4779
4963
|
const cmds = newItems.map((it) => `cp -a '/src/${it}' '/dst/${it}'`);
|
|
4780
|
-
const apply = await
|
|
4964
|
+
const apply = await execa7(
|
|
4781
4965
|
"docker",
|
|
4782
4966
|
[
|
|
4783
4967
|
"run",
|
|
@@ -4859,10 +5043,10 @@ async function ensureOpencodeVolume(spec, opts) {
|
|
|
4859
5043
|
}
|
|
4860
5044
|
steps.push("chown -R 1000:1000 /dst");
|
|
4861
5045
|
args.push(opts.image, "sh", "-c", steps.join(" && "));
|
|
4862
|
-
await
|
|
5046
|
+
await execa8("docker", args);
|
|
4863
5047
|
return { created, synced: true };
|
|
4864
5048
|
}
|
|
4865
|
-
await
|
|
5049
|
+
await execa8(
|
|
4866
5050
|
"docker",
|
|
4867
5051
|
[
|
|
4868
5052
|
"run",
|
|
@@ -4882,7 +5066,7 @@ async function ensureOpencodeVolume(spec, opts) {
|
|
|
4882
5066
|
}
|
|
4883
5067
|
async function seedOpencodePlugin(volume, image) {
|
|
4884
5068
|
try {
|
|
4885
|
-
const { stdout } = await
|
|
5069
|
+
const { stdout } = await execa8("docker", [
|
|
4886
5070
|
"run",
|
|
4887
5071
|
"--rm",
|
|
4888
5072
|
"--user",
|
|
@@ -4930,14 +5114,14 @@ var OpencodeSessionError = class extends Error {
|
|
|
4930
5114
|
}
|
|
4931
5115
|
};
|
|
4932
5116
|
async function ensureOpencodeInstalled(container, opts = {}) {
|
|
4933
|
-
const probe = await
|
|
5117
|
+
const probe = await execa8(
|
|
4934
5118
|
"docker",
|
|
4935
5119
|
["exec", "--user", CONTAINER_USER, container, "sh", "-c", "command -v opencode"],
|
|
4936
5120
|
{ reject: false }
|
|
4937
5121
|
);
|
|
4938
5122
|
if (probe.exitCode === 0) return { installed: false };
|
|
4939
5123
|
opts.onProgress?.("installing opencode (absent from this box image)");
|
|
4940
|
-
const install = await
|
|
5124
|
+
const install = await execa8(
|
|
4941
5125
|
"docker",
|
|
4942
5126
|
["exec", "--user", "root", container, "bash", "-lc", "npm install -g opencode-ai 2>&1"],
|
|
4943
5127
|
{ reject: false }
|
|
@@ -4959,7 +5143,7 @@ async function startOpencodeSession(opts) {
|
|
|
4959
5143
|
const v = process.env[k];
|
|
4960
5144
|
if (typeof v === "string" && v.length > 0) envFlags.push("-e", `${k}=${v}`);
|
|
4961
5145
|
}
|
|
4962
|
-
const result = await
|
|
5146
|
+
const result = await execa8(
|
|
4963
5147
|
"docker",
|
|
4964
5148
|
[
|
|
4965
5149
|
"exec",
|
|
@@ -5045,7 +5229,7 @@ function runInteractiveOpencodeLogin(dockerArgv) {
|
|
|
5045
5229
|
return { exitCode: child.status ?? 1 };
|
|
5046
5230
|
}
|
|
5047
5231
|
async function volumeHasOpencodeAuth(volume, image) {
|
|
5048
|
-
const res = await
|
|
5232
|
+
const res = await execa8(
|
|
5049
5233
|
"docker",
|
|
5050
5234
|
["run", "--rm", "-v", `${volume}:/dst`, image, "sh", "-c", "test -e /dst/auth.json"],
|
|
5051
5235
|
{ reject: false }
|
|
@@ -5054,7 +5238,7 @@ async function volumeHasOpencodeAuth(volume, image) {
|
|
|
5054
5238
|
}
|
|
5055
5239
|
async function opencodeSessionInfo(container, sessionName) {
|
|
5056
5240
|
const name = sessionName ?? DEFAULT_OPENCODE_SESSION;
|
|
5057
|
-
const has = await
|
|
5241
|
+
const has = await execa8(
|
|
5058
5242
|
"docker",
|
|
5059
5243
|
["exec", "--user", CONTAINER_USER, container, "tmux", "has-session", "-t", name],
|
|
5060
5244
|
{ reject: false }
|
|
@@ -5062,7 +5246,7 @@ async function opencodeSessionInfo(container, sessionName) {
|
|
|
5062
5246
|
if (has.exitCode !== 0) {
|
|
5063
5247
|
return { running: false, sessionName: name, startedAt: null };
|
|
5064
5248
|
}
|
|
5065
|
-
const ts = await
|
|
5249
|
+
const ts = await execa8(
|
|
5066
5250
|
"docker",
|
|
5067
5251
|
[
|
|
5068
5252
|
"exec",
|
|
@@ -5100,7 +5284,7 @@ var OPENCODE_PULL_CONFIG_ITEMS = [
|
|
|
5100
5284
|
async function pullOpencodeConfig(spec, opts) {
|
|
5101
5285
|
const hostData = join6(homedir5(), ".local", "share", "opencode");
|
|
5102
5286
|
const hostConfig = join6(homedir5(), ".config", "opencode");
|
|
5103
|
-
const inv = await
|
|
5287
|
+
const inv = await execa8(
|
|
5104
5288
|
"docker",
|
|
5105
5289
|
[
|
|
5106
5290
|
"run",
|
|
@@ -5142,7 +5326,7 @@ async function pullOpencodeConfig(spec, opts) {
|
|
|
5142
5326
|
const cmds = newItems.map(
|
|
5143
5327
|
(i) => `cp -a '${i.src}' '${i.hostDst === "data" ? "/dst-data" : "/dst-config"}/${i.name}'`
|
|
5144
5328
|
);
|
|
5145
|
-
const apply = await
|
|
5329
|
+
const apply = await execa8(
|
|
5146
5330
|
"docker",
|
|
5147
5331
|
[
|
|
5148
5332
|
"run",
|
|
@@ -5253,9 +5437,9 @@ function gitWorktreePathFor(branch) {
|
|
|
5253
5437
|
return `${WORKTREE_ROOT}/${fsSafeBranch(branch)}`;
|
|
5254
5438
|
}
|
|
5255
5439
|
async function collectRepoCarryOver(repo, branch, containerPath, gitWorktreePath) {
|
|
5256
|
-
const stash = await
|
|
5440
|
+
const stash = await execa9("git", ["-C", repo.hostMainRepo, "stash", "create"], { reject: false });
|
|
5257
5441
|
const stashSha = stash.exitCode === 0 ? stash.stdout.trim() || null : null;
|
|
5258
|
-
const untracked = await
|
|
5442
|
+
const untracked = await execa9(
|
|
5259
5443
|
"git",
|
|
5260
5444
|
["-C", repo.hostMainRepo, "ls-files", "--others", "--exclude-standard", "-z"],
|
|
5261
5445
|
{ reject: false }
|
|
@@ -5272,7 +5456,7 @@ async function collectRepoCarryOver(repo, branch, containerPath, gitWorktreePath
|
|
|
5272
5456
|
};
|
|
5273
5457
|
}
|
|
5274
5458
|
async function dexec(container, argv, user = "vscode", cwd = "/") {
|
|
5275
|
-
const r = await
|
|
5459
|
+
const r = await execa9(
|
|
5276
5460
|
"docker",
|
|
5277
5461
|
["exec", "-w", cwd, "--user", user, container, ...argv],
|
|
5278
5462
|
{ reject: false }
|
|
@@ -5304,7 +5488,7 @@ async function bindWorktrees(container, binds, onLog) {
|
|
|
5304
5488
|
(a, b) => a.kind === "root" && b.kind !== "root" ? -1 : a.kind !== "root" && b.kind === "root" ? 1 : 0
|
|
5305
5489
|
);
|
|
5306
5490
|
for (const b of ordered) {
|
|
5307
|
-
await
|
|
5491
|
+
await execa9(
|
|
5308
5492
|
"docker",
|
|
5309
5493
|
["exec", "-w", "/", "--user", "root", container, "sh", "-c", `mountpoint -q ${b.containerPath} && umount ${b.containerPath} || true`],
|
|
5310
5494
|
{ reject: false }
|
|
@@ -5326,7 +5510,7 @@ async function seedWorkspace(opts) {
|
|
|
5326
5510
|
const wt = r.gitWorktreePath;
|
|
5327
5511
|
const baseRef = r.repo.kind === "root" ? opts.fromBranch ?? "HEAD" : "HEAD";
|
|
5328
5512
|
const addArgs = r.reuseBranch ? ["worktree", "add", wt, r.branch] : ["worktree", "add", "-b", r.branch, wt, baseRef];
|
|
5329
|
-
const add = await
|
|
5513
|
+
const add = await execa9(
|
|
5330
5514
|
"docker",
|
|
5331
5515
|
["exec", "--user", "vscode", opts.container, "git", "-C", main, ...addArgs],
|
|
5332
5516
|
{ reject: false }
|
|
@@ -5337,7 +5521,7 @@ async function seedWorkspace(opts) {
|
|
|
5337
5521
|
);
|
|
5338
5522
|
}
|
|
5339
5523
|
log(`worktree ${wt} on branch ${r.branch} (host main ${main})`);
|
|
5340
|
-
await
|
|
5524
|
+
await execa9(
|
|
5341
5525
|
"docker",
|
|
5342
5526
|
[
|
|
5343
5527
|
"exec",
|
|
@@ -5353,7 +5537,7 @@ async function seedWorkspace(opts) {
|
|
|
5353
5537
|
],
|
|
5354
5538
|
{ reject: false }
|
|
5355
5539
|
);
|
|
5356
|
-
await
|
|
5540
|
+
await execa9(
|
|
5357
5541
|
"docker",
|
|
5358
5542
|
[
|
|
5359
5543
|
"exec",
|
|
@@ -5383,7 +5567,7 @@ async function seedWorkspace(opts) {
|
|
|
5383
5567
|
for (const r of opts.repos) {
|
|
5384
5568
|
const ct = r.containerPath;
|
|
5385
5569
|
if (r.stashSha) {
|
|
5386
|
-
const withIndex = await
|
|
5570
|
+
const withIndex = await execa9(
|
|
5387
5571
|
"docker",
|
|
5388
5572
|
[
|
|
5389
5573
|
"exec",
|
|
@@ -5401,7 +5585,7 @@ async function seedWorkspace(opts) {
|
|
|
5401
5585
|
{ reject: false }
|
|
5402
5586
|
);
|
|
5403
5587
|
if (withIndex.exitCode !== 0) {
|
|
5404
|
-
const noIndex = await
|
|
5588
|
+
const noIndex = await execa9(
|
|
5405
5589
|
"docker",
|
|
5406
5590
|
[
|
|
5407
5591
|
"exec",
|
|
@@ -5429,7 +5613,7 @@ async function seedWorkspace(opts) {
|
|
|
5429
5613
|
}
|
|
5430
5614
|
}
|
|
5431
5615
|
if (r.untrackedNul.length > 0) {
|
|
5432
|
-
const tarOut = await
|
|
5616
|
+
const tarOut = await execa9("tar", ["-C", r.hostSource, "--null", "-T", "-", "-cf", "-"], {
|
|
5433
5617
|
input: r.untrackedNul.replace(/\0$/, ""),
|
|
5434
5618
|
encoding: "buffer",
|
|
5435
5619
|
reject: false
|
|
@@ -5438,7 +5622,7 @@ async function seedWorkspace(opts) {
|
|
|
5438
5622
|
log(`warning: tar of untracked files for ${r.repo.hostMainRepo} failed: ${tarOut.stderr}`);
|
|
5439
5623
|
continue;
|
|
5440
5624
|
}
|
|
5441
|
-
const tarIn = await
|
|
5625
|
+
const tarIn = await execa9(
|
|
5442
5626
|
"docker",
|
|
5443
5627
|
["exec", "-i", "--user", "vscode", opts.container, "tar", "-C", ct, "-xf", "-"],
|
|
5444
5628
|
{ input: tarOut.stdout, reject: false }
|
|
@@ -5491,7 +5675,7 @@ async function regenerateRestoredWorktrees(opts) {
|
|
|
5491
5675
|
for (const p of opts.plans) {
|
|
5492
5676
|
const baseRef = p.kind === "root" ? opts.fromBranch ?? "HEAD" : "HEAD";
|
|
5493
5677
|
const metaDir = `${p.hostMainRepo}/.git/worktrees/${fsSafeBranch(p.freshBranch)}`;
|
|
5494
|
-
const r = await
|
|
5678
|
+
const r = await execa9(
|
|
5495
5679
|
"docker",
|
|
5496
5680
|
[
|
|
5497
5681
|
"exec",
|
|
@@ -5524,14 +5708,14 @@ async function regenerateRestoredWorktrees(opts) {
|
|
|
5524
5708
|
async function seedWorkspaceFromDir(opts) {
|
|
5525
5709
|
const log = opts.onLog ?? (() => {
|
|
5526
5710
|
});
|
|
5527
|
-
const tarOut = await
|
|
5711
|
+
const tarOut = await execa9("tar", ["-C", opts.hostSource, "-cf", "-", "."], {
|
|
5528
5712
|
encoding: "buffer",
|
|
5529
5713
|
reject: false
|
|
5530
5714
|
});
|
|
5531
5715
|
if (tarOut.exitCode !== 0) {
|
|
5532
5716
|
throw new GitWorktreeError(`tar of ${opts.hostSource} failed: ${tarOut.stderr}`);
|
|
5533
5717
|
}
|
|
5534
|
-
const tarIn = await
|
|
5718
|
+
const tarIn = await execa9(
|
|
5535
5719
|
"docker",
|
|
5536
5720
|
["exec", "-i", "--user", "1000:1000", opts.container, "tar", "-C", "/workspace", "-xf", "-"],
|
|
5537
5721
|
{ input: tarOut.stdout, reject: false }
|
|
@@ -5542,13 +5726,13 @@ async function seedWorkspaceFromDir(opts) {
|
|
|
5542
5726
|
log(`seeded /workspace from ${opts.hostSource}`);
|
|
5543
5727
|
}
|
|
5544
5728
|
async function removeInBoxWorktree(args) {
|
|
5545
|
-
const remove = await
|
|
5729
|
+
const remove = await execa9(
|
|
5546
5730
|
"git",
|
|
5547
5731
|
["-C", args.hostMainRepo, "worktree", "remove", "--force", args.gitWorktreePath],
|
|
5548
5732
|
{ reject: false }
|
|
5549
5733
|
);
|
|
5550
5734
|
if (remove.exitCode === 0) return;
|
|
5551
|
-
await
|
|
5735
|
+
await execa9("git", ["-C", args.hostMainRepo, "worktree", "prune"], { reject: false });
|
|
5552
5736
|
}
|
|
5553
5737
|
function ctParent(p) {
|
|
5554
5738
|
const i = p.lastIndexOf("/");
|
|
@@ -5579,20 +5763,20 @@ async function resyncWorkspaceFromHost(opts) {
|
|
|
5579
5763
|
const hostMain = w.hostMainRepo;
|
|
5580
5764
|
const boxBranch = w.branch;
|
|
5581
5765
|
const res = { containerPath: ct, mergeConflicts: [], overlaySkipped: [] };
|
|
5582
|
-
const hostBranchProbe = await
|
|
5766
|
+
const hostBranchProbe = await execa9(
|
|
5583
5767
|
"git",
|
|
5584
5768
|
["-C", hostMain, "symbolic-ref", "--short", "-q", "HEAD"],
|
|
5585
5769
|
{ reject: false }
|
|
5586
5770
|
);
|
|
5587
|
-
const hostRef = hostBranchProbe.exitCode === 0 && hostBranchProbe.stdout.trim() ? hostBranchProbe.stdout.trim() : (await
|
|
5771
|
+
const hostRef = hostBranchProbe.exitCode === 0 && hostBranchProbe.stdout.trim() ? hostBranchProbe.stdout.trim() : (await execa9("git", ["-C", hostMain, "rev-parse", "HEAD"], { reject: false })).stdout.trim();
|
|
5588
5772
|
if (!hostRef) {
|
|
5589
5773
|
log(`resync: ${ct}: could not resolve host ref; skipping`);
|
|
5590
5774
|
results.push(res);
|
|
5591
5775
|
continue;
|
|
5592
5776
|
}
|
|
5593
|
-
const stash = await
|
|
5777
|
+
const stash = await execa9("git", ["-C", hostMain, "stash", "create"], { reject: false });
|
|
5594
5778
|
const hostStashSha = stash.exitCode === 0 ? stash.stdout.trim() || null : null;
|
|
5595
|
-
const untracked = await
|
|
5779
|
+
const untracked = await execa9(
|
|
5596
5780
|
"git",
|
|
5597
5781
|
["-C", hostMain, "ls-files", "--others", "--exclude-standard", "-z"],
|
|
5598
5782
|
{ reject: false }
|
|
@@ -5662,7 +5846,7 @@ async function resyncWorkspaceFromHost(opts) {
|
|
|
5662
5846
|
}
|
|
5663
5847
|
}
|
|
5664
5848
|
if (hostUntracked.length > 0) {
|
|
5665
|
-
const probe = await
|
|
5849
|
+
const probe = await execa9(
|
|
5666
5850
|
"docker",
|
|
5667
5851
|
[
|
|
5668
5852
|
"exec",
|
|
@@ -5709,13 +5893,13 @@ async function resyncWorkspaceFromHost(opts) {
|
|
|
5709
5893
|
log(`resync: ${ct}: ${String(identical)} untracked host file(s) already identical in box (no-op)`);
|
|
5710
5894
|
}
|
|
5711
5895
|
if (toCopy.length > 0) {
|
|
5712
|
-
const tarOut = await
|
|
5896
|
+
const tarOut = await execa9("tar", ["-C", hostMain, "--null", "-T", "-", "-cf", "-"], {
|
|
5713
5897
|
input: toCopy.join("\0"),
|
|
5714
5898
|
encoding: "buffer",
|
|
5715
5899
|
reject: false
|
|
5716
5900
|
});
|
|
5717
5901
|
if (tarOut.exitCode === 0) {
|
|
5718
|
-
await
|
|
5902
|
+
await execa9(
|
|
5719
5903
|
"docker",
|
|
5720
5904
|
["exec", "-i", "--user", "vscode", opts.container, "tar", "-C", ct, "-xf", "-"],
|
|
5721
5905
|
{ input: tarOut.stdout, reject: false }
|
|
@@ -5738,7 +5922,7 @@ var cached = null;
|
|
|
5738
5922
|
async function detectPortless() {
|
|
5739
5923
|
if (cached !== null) return cached;
|
|
5740
5924
|
try {
|
|
5741
|
-
const ver = await
|
|
5925
|
+
const ver = await execa10(PORTLESS_BIN, SUB_VERSION, { reject: false });
|
|
5742
5926
|
if (ver.exitCode !== 0) {
|
|
5743
5927
|
cached = { installed: false, proxyRunning: false };
|
|
5744
5928
|
return cached;
|
|
@@ -5758,7 +5942,7 @@ function resetPortlessCache() {
|
|
|
5758
5942
|
}
|
|
5759
5943
|
async function portlessAlias(name, port) {
|
|
5760
5944
|
try {
|
|
5761
|
-
const r = await
|
|
5945
|
+
const r = await execa10(PORTLESS_BIN, [SUB_ALIAS, name, String(port)], { reject: false });
|
|
5762
5946
|
return r.exitCode === 0;
|
|
5763
5947
|
} catch {
|
|
5764
5948
|
return false;
|
|
@@ -5766,7 +5950,7 @@ async function portlessAlias(name, port) {
|
|
|
5766
5950
|
}
|
|
5767
5951
|
async function portlessUnalias(name) {
|
|
5768
5952
|
try {
|
|
5769
|
-
const r = await
|
|
5953
|
+
const r = await execa10(PORTLESS_BIN, [SUB_ALIAS, SUB_ALIAS_REMOVE, name], { reject: false });
|
|
5770
5954
|
return r.exitCode === 0;
|
|
5771
5955
|
} catch {
|
|
5772
5956
|
return false;
|
|
@@ -5775,7 +5959,7 @@ async function portlessUnalias(name) {
|
|
|
5775
5959
|
async function portlessGetUrl(name) {
|
|
5776
5960
|
const fallback = `https://${name}.localhost`;
|
|
5777
5961
|
try {
|
|
5778
|
-
const r = await
|
|
5962
|
+
const r = await execa10(PORTLESS_BIN, [SUB_GET, name], { reject: false });
|
|
5779
5963
|
const out = (r.stdout ?? "").trim();
|
|
5780
5964
|
if (r.exitCode === 0 && /^https?:\/\//.test(out)) return out;
|
|
5781
5965
|
} catch {
|
|
@@ -5796,7 +5980,7 @@ function portlessBrowserEnv(boxName, opts) {
|
|
|
5796
5980
|
}
|
|
5797
5981
|
async function installPortless() {
|
|
5798
5982
|
try {
|
|
5799
|
-
const r = await
|
|
5983
|
+
const r = await execa10("npm", ["install", "-g", "portless"], { reject: false });
|
|
5800
5984
|
return r.exitCode === 0;
|
|
5801
5985
|
} catch {
|
|
5802
5986
|
return false;
|
|
@@ -5804,7 +5988,7 @@ async function installPortless() {
|
|
|
5804
5988
|
}
|
|
5805
5989
|
async function startPortlessProxy() {
|
|
5806
5990
|
try {
|
|
5807
|
-
const r = await
|
|
5991
|
+
const r = await execa10(
|
|
5808
5992
|
PORTLESS_BIN,
|
|
5809
5993
|
["proxy", "start", "--no-tls", "-p", String(PORTLESS_PROXY_PORT)],
|
|
5810
5994
|
{ reject: false }
|
|
@@ -5851,14 +6035,14 @@ async function resolvePortlessHostStateDir(override) {
|
|
|
5851
6035
|
const live = await findLivePortlessStateDir();
|
|
5852
6036
|
if (live) return live;
|
|
5853
6037
|
const home = join8(homedir6(), ".portless");
|
|
5854
|
-
if (
|
|
5855
|
-
if (
|
|
6038
|
+
if (existsSync2(home)) return home;
|
|
6039
|
+
if (existsSync2("/tmp/portless")) return "/tmp/portless";
|
|
5856
6040
|
return home;
|
|
5857
6041
|
}
|
|
5858
6042
|
async function isProxyRunning() {
|
|
5859
6043
|
if (await findLivePortlessStateDir() !== null) return true;
|
|
5860
6044
|
try {
|
|
5861
|
-
const r = await
|
|
6045
|
+
const r = await execa10("pgrep", ["-f", "portless proxy"], { reject: false });
|
|
5862
6046
|
return r.exitCode === 0 && (r.stdout ?? "").trim().length > 0;
|
|
5863
6047
|
} catch {
|
|
5864
6048
|
return false;
|
|
@@ -5909,12 +6093,12 @@ async function findExcludedDirs(root, excluded = EXCLUDE_DIRS) {
|
|
|
5909
6093
|
return matches;
|
|
5910
6094
|
}
|
|
5911
6095
|
async function createSnapshot(opts) {
|
|
5912
|
-
const source =
|
|
5913
|
-
const destination =
|
|
6096
|
+
const source = resolve22(opts.source);
|
|
6097
|
+
const destination = resolve22(opts.destination);
|
|
5914
6098
|
const excluded = opts.excluded ?? EXCLUDE_DIRS;
|
|
5915
6099
|
await mkdir42(SNAPSHOTS_ROOT, { recursive: true });
|
|
5916
6100
|
const cpArgs = platform() === "darwin" ? ["-cR"] : ["-R"];
|
|
5917
|
-
await
|
|
6101
|
+
await execa11("cp", [...cpArgs, `${source}/`, destination]);
|
|
5918
6102
|
const toPrune = await findExcludedDirs(destination, excluded);
|
|
5919
6103
|
await Promise.all(toPrune.map((p) => rm32(p, { recursive: true, force: true })));
|
|
5920
6104
|
return { destination, prunedPaths: toPrune };
|
|
@@ -5922,7 +6106,7 @@ async function createSnapshot(opts) {
|
|
|
5922
6106
|
var CHECKPOINTS_ROOT = join10(homedir8(), ".agentbox", "checkpoints");
|
|
5923
6107
|
var CHECKPOINT_IMAGE_PREFIX = "agentbox-ckpt-";
|
|
5924
6108
|
function checkpointImageTag(projectRoot, name) {
|
|
5925
|
-
const mnemonic = sanitizeMnemonic(
|
|
6109
|
+
const mnemonic = sanitizeMnemonic(basename4(projectRoot));
|
|
5926
6110
|
return `${CHECKPOINT_IMAGE_PREFIX}${hashProjectPath(projectRoot)}_${mnemonic}:${name}`;
|
|
5927
6111
|
}
|
|
5928
6112
|
function projectCheckpointsDir(projectRoot) {
|
|
@@ -6039,7 +6223,7 @@ async function runCleanup(container, log) {
|
|
|
6039
6223
|
}
|
|
6040
6224
|
}
|
|
6041
6225
|
async function inspectImageConfig(imageRef) {
|
|
6042
|
-
const r = await
|
|
6226
|
+
const r = await execa12("docker", ["image", "inspect", imageRef], { reject: false });
|
|
6043
6227
|
if (r.exitCode !== 0) {
|
|
6044
6228
|
throw new CheckpointError(`docker image inspect ${imageRef} failed`, r.stdout, r.stderr);
|
|
6045
6229
|
}
|
|
@@ -6115,14 +6299,14 @@ async function createCheckpoint(opts) {
|
|
|
6115
6299
|
await runCleanup(box.container, log);
|
|
6116
6300
|
if (type === "layered") {
|
|
6117
6301
|
log(`docker commit ${box.container} -> ${tag} (layered)`);
|
|
6118
|
-
const r = await
|
|
6302
|
+
const r = await execa12("docker", ["commit", box.container, tag], { reject: false });
|
|
6119
6303
|
if (r.exitCode !== 0) {
|
|
6120
6304
|
throw new CheckpointError(`docker commit failed for ${box.container}`, r.stdout, r.stderr);
|
|
6121
6305
|
}
|
|
6122
6306
|
} else {
|
|
6123
6307
|
log(`docker commit ${box.container} -> <intermediate> (flattened path)`);
|
|
6124
6308
|
const intermediate = `${tag}-intermediate`;
|
|
6125
|
-
const commit = await
|
|
6309
|
+
const commit = await execa12("docker", ["commit", box.container, intermediate], {
|
|
6126
6310
|
reject: false
|
|
6127
6311
|
});
|
|
6128
6312
|
if (commit.exitCode !== 0) {
|
|
@@ -6167,7 +6351,7 @@ async function createCheckpoint(opts) {
|
|
|
6167
6351
|
}
|
|
6168
6352
|
async function flattenImage(sourceTag, destTag, log) {
|
|
6169
6353
|
const tmpName = `agentbox-flatten-${Date.now().toString(36)}`;
|
|
6170
|
-
const create = await
|
|
6354
|
+
const create = await execa12(
|
|
6171
6355
|
"docker",
|
|
6172
6356
|
["create", "--name", tmpName, sourceTag, "sleep", "0"],
|
|
6173
6357
|
{ reject: false }
|
|
@@ -6179,7 +6363,7 @@ async function flattenImage(sourceTag, destTag, log) {
|
|
|
6179
6363
|
try {
|
|
6180
6364
|
const rootfsPath = join10(scratch, "rootfs.tar");
|
|
6181
6365
|
log(`exporting rootfs of ${sourceTag} to ${rootfsPath}`);
|
|
6182
|
-
const exp = await
|
|
6366
|
+
const exp = await execa12("docker", ["export", "-o", rootfsPath, tmpName], { reject: false });
|
|
6183
6367
|
if (exp.exitCode !== 0) {
|
|
6184
6368
|
throw new CheckpointError(`docker export failed`, exp.stdout, exp.stderr);
|
|
6185
6369
|
}
|
|
@@ -6192,7 +6376,7 @@ async function flattenImage(sourceTag, destTag, log) {
|
|
|
6192
6376
|
];
|
|
6193
6377
|
await writeFile32(join10(scratch, "Dockerfile"), lines.join("\n") + "\n", "utf8");
|
|
6194
6378
|
log(`building flattened ${destTag} from rootfs.tar (FROM scratch)`);
|
|
6195
|
-
const build = await
|
|
6379
|
+
const build = await execa12(
|
|
6196
6380
|
"docker",
|
|
6197
6381
|
["build", "-t", destTag, "-f", join10(scratch, "Dockerfile"), scratch],
|
|
6198
6382
|
{ reject: false }
|
|
@@ -6201,7 +6385,7 @@ async function flattenImage(sourceTag, destTag, log) {
|
|
|
6201
6385
|
throw new CheckpointError(`flatten docker build failed`, build.stdout, build.stderr);
|
|
6202
6386
|
}
|
|
6203
6387
|
} finally {
|
|
6204
|
-
await
|
|
6388
|
+
await execa12("docker", ["rm", "-f", tmpName], { reject: false });
|
|
6205
6389
|
await rm4(scratch, { recursive: true, force: true });
|
|
6206
6390
|
}
|
|
6207
6391
|
}
|
|
@@ -6245,7 +6429,7 @@ async function pathExists5(p) {
|
|
|
6245
6429
|
}
|
|
6246
6430
|
async function writeBoxEnvFile(container, env) {
|
|
6247
6431
|
const body = formatBoxEnvBody(env);
|
|
6248
|
-
const result = await
|
|
6432
|
+
const result = await execa13(
|
|
6249
6433
|
"docker",
|
|
6250
6434
|
["exec", "--user", "root", "-i", container, "sh", "-c", "umask 022 && cat > /etc/agentbox/box.env"],
|
|
6251
6435
|
{ input: body, reject: false }
|
|
@@ -6269,7 +6453,7 @@ function shellSingleQuote(s) {
|
|
|
6269
6453
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
6270
6454
|
}
|
|
6271
6455
|
async function ensureHomeOwnedByVscode(container) {
|
|
6272
|
-
await
|
|
6456
|
+
await execa14(
|
|
6273
6457
|
"docker",
|
|
6274
6458
|
[
|
|
6275
6459
|
"exec",
|
|
@@ -6418,16 +6602,16 @@ async function spawnRelay(relayBin, cliEntry, log) {
|
|
|
6418
6602
|
}
|
|
6419
6603
|
function resolveRelayBin() {
|
|
6420
6604
|
const override = process.env.AGENTBOX_RELAY_BIN;
|
|
6421
|
-
if (override &&
|
|
6422
|
-
const here =
|
|
6605
|
+
if (override && existsSync3(override)) return override;
|
|
6606
|
+
const here = dirname22(fileURLToPath(import.meta.url));
|
|
6423
6607
|
const candidates = [
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6608
|
+
resolve3(here, "..", "runtime", "relay", "bin.cjs"),
|
|
6609
|
+
resolve3(here, "..", "..", "relay", "dist", "bin.cjs"),
|
|
6610
|
+
resolve3(here, "..", "..", "..", "@agentbox", "relay", "dist", "bin.cjs"),
|
|
6611
|
+
resolve3(here, "..", "..", "node_modules", "@agentbox", "relay", "dist", "bin.cjs")
|
|
6428
6612
|
];
|
|
6429
6613
|
for (const c of candidates) {
|
|
6430
|
-
if (
|
|
6614
|
+
if (existsSync3(c)) return c;
|
|
6431
6615
|
}
|
|
6432
6616
|
throw new Error(
|
|
6433
6617
|
`could not locate @agentbox/relay bin; tried:
|
|
@@ -6436,29 +6620,29 @@ function resolveRelayBin() {
|
|
|
6436
6620
|
}
|
|
6437
6621
|
function resolveCliEntry() {
|
|
6438
6622
|
const override = process.env.AGENTBOX_CLI_ENTRY;
|
|
6439
|
-
if (override &&
|
|
6440
|
-
const here =
|
|
6623
|
+
if (override && existsSync3(override)) return override;
|
|
6624
|
+
const here = dirname22(fileURLToPath(import.meta.url));
|
|
6441
6625
|
const candidates = [
|
|
6442
6626
|
// Bundled CLI (dev + published): this module IS bundled into the CLI
|
|
6443
6627
|
// entry, so the entry is index.js next to this file.
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6628
|
+
resolve3(here, "index.js"),
|
|
6629
|
+
resolve3(here, "..", "..", "..", "apps", "cli", "dist", "index.js"),
|
|
6630
|
+
resolve3(here, "..", "..", "..", "..", "dist", "index.js")
|
|
6447
6631
|
];
|
|
6448
6632
|
for (const c of candidates) {
|
|
6449
|
-
if (
|
|
6633
|
+
if (existsSync3(c)) return c;
|
|
6450
6634
|
}
|
|
6451
6635
|
return null;
|
|
6452
6636
|
}
|
|
6453
6637
|
async function stageRelayHome(version, log) {
|
|
6454
6638
|
if (!version || version === "0.0.0-dev") return null;
|
|
6455
6639
|
if (process.env.AGENTBOX_RELAY_BIN || process.env.AGENTBOX_CLI_ENTRY) return null;
|
|
6456
|
-
const cliRoot = findCliRoot(
|
|
6640
|
+
const cliRoot = findCliRoot(dirname22(fileURLToPath(import.meta.url)));
|
|
6457
6641
|
if (cliRoot === null) return null;
|
|
6458
6642
|
const homeDir = join11(RELAY_HOME_DIR, version);
|
|
6459
6643
|
const stagedEntry = join11(homeDir, "dist", "index.js");
|
|
6460
6644
|
const stagedBin = join11(homeDir, "runtime", "relay", "bin.cjs");
|
|
6461
|
-
if (
|
|
6645
|
+
if (existsSync3(stagedEntry) && existsSync3(stagedBin)) {
|
|
6462
6646
|
return { relayBin: stagedBin, cliEntry: stagedEntry };
|
|
6463
6647
|
}
|
|
6464
6648
|
const nodeModules = resolveDepRoot(join11(cliRoot, "dist", "index.js"));
|
|
@@ -6470,7 +6654,7 @@ async function stageRelayHome(version, log) {
|
|
|
6470
6654
|
await mkdir6(tmpDir, { recursive: true });
|
|
6471
6655
|
for (const sub of ["dist", "runtime", "share"]) {
|
|
6472
6656
|
const src = join11(cliRoot, sub);
|
|
6473
|
-
if (
|
|
6657
|
+
if (existsSync3(src)) await cp(src, join11(tmpDir, sub), { recursive: true });
|
|
6474
6658
|
}
|
|
6475
6659
|
await cp(nodeModules, join11(tmpDir, "node_modules"), { recursive: true, dereference: true });
|
|
6476
6660
|
await rm5(homeDir, { recursive: true, force: true });
|
|
@@ -6478,7 +6662,7 @@ async function stageRelayHome(version, log) {
|
|
|
6478
6662
|
} catch (err) {
|
|
6479
6663
|
await rm5(tmpDir, { recursive: true, force: true }).catch(() => {
|
|
6480
6664
|
});
|
|
6481
|
-
if (
|
|
6665
|
+
if (existsSync3(stagedEntry) && existsSync3(stagedBin)) {
|
|
6482
6666
|
return { relayBin: stagedBin, cliEntry: stagedEntry };
|
|
6483
6667
|
}
|
|
6484
6668
|
log(`relay home staging failed (${err instanceof Error ? err.message : String(err)}); using bundle paths`);
|
|
@@ -6490,8 +6674,8 @@ async function stageRelayHome(version, log) {
|
|
|
6490
6674
|
return { relayBin: stagedBin, cliEntry: stagedEntry };
|
|
6491
6675
|
}
|
|
6492
6676
|
function findCliRoot(moduleDir) {
|
|
6493
|
-
for (const root of [
|
|
6494
|
-
if (
|
|
6677
|
+
for (const root of [resolve3(moduleDir, ".."), resolve3(moduleDir, "..", "..")]) {
|
|
6678
|
+
if (existsSync3(join11(root, "dist", "index.js")) && existsSync3(join11(root, "runtime", "relay", "bin.cjs"))) {
|
|
6495
6679
|
return root;
|
|
6496
6680
|
}
|
|
6497
6681
|
}
|
|
@@ -6506,7 +6690,7 @@ function resolveDepRoot(fromFile) {
|
|
|
6506
6690
|
const idx = main.lastIndexOf(marker);
|
|
6507
6691
|
if (idx === -1) return null;
|
|
6508
6692
|
const nm = main.slice(0, idx + marker.length - 1);
|
|
6509
|
-
return
|
|
6693
|
+
return existsSync3(join11(nm, "commander")) ? nm : null;
|
|
6510
6694
|
} catch {
|
|
6511
6695
|
return null;
|
|
6512
6696
|
}
|
|
@@ -6667,7 +6851,8 @@ async function registerBoxWithRelay(args) {
|
|
|
6667
6851
|
worktrees,
|
|
6668
6852
|
previewUrl: args.previewUrl,
|
|
6669
6853
|
previewToken: args.previewToken,
|
|
6670
|
-
bridgeToken: args.bridgeToken
|
|
6854
|
+
bridgeToken: args.bridgeToken,
|
|
6855
|
+
autoApproveHostActions: args.autoApproveHostActions
|
|
6671
6856
|
});
|
|
6672
6857
|
}
|
|
6673
6858
|
async function forgetBoxFromRelay(boxId) {
|
|
@@ -6808,7 +6993,8 @@ async function rehydrateRelayRegistry(boxes) {
|
|
|
6808
6993
|
worktrees: b.gitWorktrees,
|
|
6809
6994
|
previewUrl: b.relayPreviewUrl,
|
|
6810
6995
|
previewToken: b.relayPreviewToken,
|
|
6811
|
-
bridgeToken: b.bridgeToken
|
|
6996
|
+
bridgeToken: b.bridgeToken,
|
|
6997
|
+
autoApproveHostActions: b.autoApproveHostActions
|
|
6812
6998
|
});
|
|
6813
6999
|
} catch {
|
|
6814
7000
|
}
|
|
@@ -6959,7 +7145,7 @@ function persistableLimits(lim) {
|
|
|
6959
7145
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
6960
7146
|
}
|
|
6961
7147
|
function sanitizeBasename(workspacePath) {
|
|
6962
|
-
const raw =
|
|
7148
|
+
const raw = basename5(resolve4(workspacePath));
|
|
6963
7149
|
return raw.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^[-._]+|[-._]+$/g, "").slice(0, 30).replace(/[-._]+$/, "");
|
|
6964
7150
|
}
|
|
6965
7151
|
function defaultBoxName(workspacePath, id) {
|
|
@@ -6990,7 +7176,7 @@ async function buildIdentityMounts() {
|
|
|
6990
7176
|
async function createBox(opts) {
|
|
6991
7177
|
const log = opts.onLog ?? (() => {
|
|
6992
7178
|
});
|
|
6993
|
-
const workspace =
|
|
7179
|
+
const workspace = resolve4(opts.workspacePath);
|
|
6994
7180
|
if (!await pathExists6(workspace)) {
|
|
6995
7181
|
throw new Error(`workspace does not exist: ${workspace}`);
|
|
6996
7182
|
}
|
|
@@ -7283,6 +7469,7 @@ async function createBox(opts) {
|
|
|
7283
7469
|
}
|
|
7284
7470
|
}
|
|
7285
7471
|
for (const v of extraVolumes) log(`mounting agent dir: ${v}`);
|
|
7472
|
+
const autoApproveHostActions = (await loadEffectiveConfig(opts.projectRoot ?? workspace)).effective.box.autoApproveHostActions;
|
|
7286
7473
|
const relayToken = generateRelayToken();
|
|
7287
7474
|
if (relayUp) {
|
|
7288
7475
|
try {
|
|
@@ -7293,7 +7480,8 @@ async function createBox(opts) {
|
|
|
7293
7480
|
containerName,
|
|
7294
7481
|
createdAt,
|
|
7295
7482
|
projectIndex,
|
|
7296
|
-
worktrees: gitWorktreeRecords
|
|
7483
|
+
worktrees: gitWorktreeRecords,
|
|
7484
|
+
autoApproveHostActions
|
|
7297
7485
|
});
|
|
7298
7486
|
log(`registered box token with relay`);
|
|
7299
7487
|
} catch (err) {
|
|
@@ -7359,6 +7547,7 @@ async function createBox(opts) {
|
|
|
7359
7547
|
gitWorktrees: gitWorktreeRecords.length > 0 ? gitWorktreeRecords : void 0,
|
|
7360
7548
|
withPlaywright: opts.withPlaywright ? true : void 0,
|
|
7361
7549
|
withEnv: opts.withEnv ? true : void 0,
|
|
7550
|
+
autoApproveHostActions: autoApproveHostActions ? true : void 0,
|
|
7362
7551
|
vncEnabled: vncEnabled ? true : void 0,
|
|
7363
7552
|
vncContainerPort: vncEnabled ? VNC_CONTAINER_PORT : void 0,
|
|
7364
7553
|
vncPassword,
|
|
@@ -7416,7 +7605,7 @@ async function createBox(opts) {
|
|
|
7416
7605
|
} catch (err) {
|
|
7417
7606
|
if (opts.useBranch !== void 0) {
|
|
7418
7607
|
log(`seedWorkspace failed for --use-branch ${opts.useBranch}; cleaning up the box`);
|
|
7419
|
-
await
|
|
7608
|
+
await execa15("docker", ["rm", "-f", containerName], { reject: false });
|
|
7420
7609
|
await removeBoxRecord(id);
|
|
7421
7610
|
for (const w of gitWorktreeRecords) {
|
|
7422
7611
|
await removeInBoxWorktree({
|
|
@@ -7479,7 +7668,7 @@ async function createBox(opts) {
|
|
|
7479
7668
|
else log(`agentbox-ctl daemon did not become reachable: ${ctl.reason}`);
|
|
7480
7669
|
if (opts.withPlaywright) {
|
|
7481
7670
|
log("installing @playwright/cli@latest (--with-playwright)");
|
|
7482
|
-
const result = await
|
|
7671
|
+
const result = await execa15(
|
|
7483
7672
|
"docker",
|
|
7484
7673
|
[
|
|
7485
7674
|
"exec",
|
|
@@ -7653,7 +7842,7 @@ function parseShellSessionList(stdout) {
|
|
|
7653
7842
|
return out;
|
|
7654
7843
|
}
|
|
7655
7844
|
async function listShellSessions(container, user) {
|
|
7656
|
-
const res = await
|
|
7845
|
+
const res = await execa16(
|
|
7657
7846
|
"docker",
|
|
7658
7847
|
[
|
|
7659
7848
|
"exec",
|
|
@@ -7677,7 +7866,7 @@ async function startShellSession(opts) {
|
|
|
7677
7866
|
const login = opts.login !== false;
|
|
7678
7867
|
const term = process.env["TERM"] ?? "xterm-256color";
|
|
7679
7868
|
const cmd = login ? "bash -l" : "bash";
|
|
7680
|
-
const result = await
|
|
7869
|
+
const result = await execa16(
|
|
7681
7870
|
"docker",
|
|
7682
7871
|
[
|
|
7683
7872
|
"exec",
|
|
@@ -7726,7 +7915,7 @@ function buildShellSessionAttachArgv(container, sessionName, user) {
|
|
|
7726
7915
|
}
|
|
7727
7916
|
async function shellSessionInfo(container, sessionName, user) {
|
|
7728
7917
|
const name = sessionName ?? DEFAULT_SHELL_SESSION;
|
|
7729
|
-
const has = await
|
|
7918
|
+
const has = await execa16(
|
|
7730
7919
|
"docker",
|
|
7731
7920
|
["exec", "--user", user ?? CONTAINER_USER, container, "tmux", "has-session", "-t", name],
|
|
7732
7921
|
{ reject: false }
|
|
@@ -7734,7 +7923,7 @@ async function shellSessionInfo(container, sessionName, user) {
|
|
|
7734
7923
|
return { running: has.exitCode === 0, sessionName: name };
|
|
7735
7924
|
}
|
|
7736
7925
|
async function killShellSession(container, sessionName, user) {
|
|
7737
|
-
const res = await
|
|
7926
|
+
const res = await execa16(
|
|
7738
7927
|
"docker",
|
|
7739
7928
|
[
|
|
7740
7929
|
"exec",
|
|
@@ -8017,7 +8206,8 @@ async function startBox(idOrName) {
|
|
|
8017
8206
|
containerName: box.container,
|
|
8018
8207
|
createdAt: box.createdAt,
|
|
8019
8208
|
projectIndex: box.projectIndex,
|
|
8020
|
-
worktrees: box.gitWorktrees
|
|
8209
|
+
worktrees: box.gitWorktrees,
|
|
8210
|
+
autoApproveHostActions: box.autoApproveHostActions
|
|
8021
8211
|
});
|
|
8022
8212
|
} catch {
|
|
8023
8213
|
}
|
|
@@ -8036,7 +8226,7 @@ async function getBoxHostPaths(idOrName) {
|
|
|
8036
8226
|
}
|
|
8037
8227
|
async function dirSizeBytes(path) {
|
|
8038
8228
|
try {
|
|
8039
|
-
const result = await
|
|
8229
|
+
const result = await execa17("du", ["-sk", path], { reject: false });
|
|
8040
8230
|
if (result.exitCode !== 0) return null;
|
|
8041
8231
|
const sizeKb = Number.parseInt((result.stdout ?? "").split(/\s+/)[0] ?? "", 10);
|
|
8042
8232
|
if (Number.isNaN(sizeKb)) return null;
|
|
@@ -8181,7 +8371,7 @@ async function listBoxDirs() {
|
|
|
8181
8371
|
}
|
|
8182
8372
|
}
|
|
8183
8373
|
async function listCheckpointImageTags() {
|
|
8184
|
-
const r = await
|
|
8374
|
+
const r = await execa17(
|
|
8185
8375
|
"docker",
|
|
8186
8376
|
["image", "ls", "--format", "{{.Repository}}:{{.Tag}}", `${CHECKPOINT_IMAGE_PREFIX}*`],
|
|
8187
8377
|
{ reject: false }
|
|
@@ -8289,7 +8479,7 @@ async function pruneBoxes(opts = {}) {
|
|
|
8289
8479
|
} catch {
|
|
8290
8480
|
}
|
|
8291
8481
|
try {
|
|
8292
|
-
await
|
|
8482
|
+
await execa17("docker", ["image", "rm", RELAY_IMAGE_REF], { reject: false });
|
|
8293
8483
|
} catch {
|
|
8294
8484
|
}
|
|
8295
8485
|
try {
|
|
@@ -8351,7 +8541,7 @@ function splitPair(raw) {
|
|
|
8351
8541
|
return [parts[0].trim(), parts[1].trim()];
|
|
8352
8542
|
}
|
|
8353
8543
|
async function duBytes(path) {
|
|
8354
|
-
const result = await
|
|
8544
|
+
const result = await execa18("du", ["-sk", path], { reject: false });
|
|
8355
8545
|
if (result.exitCode !== 0) return null;
|
|
8356
8546
|
const kb = Number.parseInt((result.stdout ?? "").split(/\s+/)[0] ?? "", 10);
|
|
8357
8547
|
return Number.isNaN(kb) ? null : kb * 1024;
|
|
@@ -8364,7 +8554,7 @@ async function volumeSizeBytes(name) {
|
|
|
8364
8554
|
const sz = await duBytes(live);
|
|
8365
8555
|
if (sz !== null) return sz;
|
|
8366
8556
|
}
|
|
8367
|
-
const df = await
|
|
8557
|
+
const df = await execa18(
|
|
8368
8558
|
"docker",
|
|
8369
8559
|
["system", "df", "-v", "--format", "{{json .Volumes}}"],
|
|
8370
8560
|
{ reject: false }
|
|
@@ -8385,7 +8575,7 @@ async function volumeSizeBytes(name) {
|
|
|
8385
8575
|
return null;
|
|
8386
8576
|
}
|
|
8387
8577
|
async function imageBytes(tag) {
|
|
8388
|
-
const r = await
|
|
8578
|
+
const r = await execa18("docker", ["image", "inspect", tag, "--format", "{{.Size}}"], {
|
|
8389
8579
|
reject: false
|
|
8390
8580
|
});
|
|
8391
8581
|
if (r.exitCode !== 0) return null;
|
|
@@ -8396,7 +8586,7 @@ async function projectCheckpointImageBytes(projectRoot, name) {
|
|
|
8396
8586
|
return imageBytes(checkpointImageTag(projectRoot, name));
|
|
8397
8587
|
}
|
|
8398
8588
|
async function allCheckpointImagesBytes() {
|
|
8399
|
-
const r = await
|
|
8589
|
+
const r = await execa18(
|
|
8400
8590
|
"docker",
|
|
8401
8591
|
[
|
|
8402
8592
|
"image",
|
|
@@ -8448,7 +8638,7 @@ function reconcileLimits(persisted, dockerJson) {
|
|
|
8448
8638
|
};
|
|
8449
8639
|
}
|
|
8450
8640
|
async function containerWritableBytes(container) {
|
|
8451
|
-
const r = await
|
|
8641
|
+
const r = await execa18(
|
|
8452
8642
|
"docker",
|
|
8453
8643
|
["ps", "-a", "--filter", `name=^${container}$`, "--format", "{{.Size}}", "--size"],
|
|
8454
8644
|
{ reject: false }
|
|
@@ -8495,7 +8685,7 @@ async function boxResourceStats(record) {
|
|
|
8495
8685
|
if (await inspectContainerStatus(record.container) !== "running") {
|
|
8496
8686
|
return base;
|
|
8497
8687
|
}
|
|
8498
|
-
const proc = await
|
|
8688
|
+
const proc = await execa18(
|
|
8499
8689
|
"docker",
|
|
8500
8690
|
["stats", "--no-stream", "--format", "{{json .}}", record.container],
|
|
8501
8691
|
{ reject: false }
|
|
@@ -8530,125 +8720,6 @@ async function boxResourceStats(record) {
|
|
|
8530
8720
|
blockWriteBytes: blkPair ? parseDockerSize(blkPair[1]) : null
|
|
8531
8721
|
};
|
|
8532
8722
|
}
|
|
8533
|
-
function posixDirname(p) {
|
|
8534
|
-
return posix.dirname(p) || "/";
|
|
8535
|
-
}
|
|
8536
|
-
function asText(s) {
|
|
8537
|
-
if (s === void 0) return "";
|
|
8538
|
-
if (typeof s === "string") return s;
|
|
8539
|
-
return Buffer.from(s).toString("utf8");
|
|
8540
|
-
}
|
|
8541
|
-
async function uploadToBox(box, hostSrc, boxDst) {
|
|
8542
|
-
const srcAbs = resolve4(hostSrc);
|
|
8543
|
-
if (!existsSync3(srcAbs)) throw new Error(`source not found: ${hostSrc}`);
|
|
8544
|
-
const srcBasename = basename5(srcAbs);
|
|
8545
|
-
const srcParent = dirname22(srcAbs);
|
|
8546
|
-
let boxParent;
|
|
8547
|
-
let finalName;
|
|
8548
|
-
if (boxDst.endsWith("/")) {
|
|
8549
|
-
boxParent = boxDst.replace(/\/+$/, "") || "/";
|
|
8550
|
-
finalName = srcBasename;
|
|
8551
|
-
} else {
|
|
8552
|
-
const isDir2 = await execa18(
|
|
8553
|
-
"docker",
|
|
8554
|
-
["exec", box.container, "test", "-d", boxDst],
|
|
8555
|
-
{ reject: false }
|
|
8556
|
-
);
|
|
8557
|
-
if (isDir2.exitCode === 0) {
|
|
8558
|
-
boxParent = boxDst.replace(/\/+$/, "") || "/";
|
|
8559
|
-
finalName = srcBasename;
|
|
8560
|
-
} else {
|
|
8561
|
-
boxParent = posixDirname(boxDst);
|
|
8562
|
-
finalName = posix.basename(boxDst);
|
|
8563
|
-
}
|
|
8564
|
-
}
|
|
8565
|
-
const finalPath = boxParent === "/" ? `/${finalName}` : `${boxParent}/${finalName}`;
|
|
8566
|
-
const mk = await execa18(
|
|
8567
|
-
"docker",
|
|
8568
|
-
["exec", "--user", "root", box.container, "mkdir", "-p", boxParent],
|
|
8569
|
-
{ reject: false }
|
|
8570
|
-
);
|
|
8571
|
-
if (mk.exitCode !== 0) {
|
|
8572
|
-
throw new Error(`mkdir -p ${boxParent} in box failed: ${asText(mk.stderr).slice(0, 300)}`);
|
|
8573
|
-
}
|
|
8574
|
-
const packed = await execa18("tar", ["-C", srcParent, "-cf", "-", srcBasename], {
|
|
8575
|
-
encoding: "buffer",
|
|
8576
|
-
reject: false,
|
|
8577
|
-
env: { ...process.env, COPYFILE_DISABLE: "1" }
|
|
8578
|
-
});
|
|
8579
|
-
if (packed.exitCode !== 0) {
|
|
8580
|
-
throw new Error(`tar pack failed: ${asText(packed.stderr).slice(0, 300)}`);
|
|
8581
|
-
}
|
|
8582
|
-
const extract = await execa18(
|
|
8583
|
-
"docker",
|
|
8584
|
-
["exec", "-i", "--user", "root", box.container, "tar", "-xf", "-", "-C", boxParent],
|
|
8585
|
-
{ input: packed.stdout, reject: false }
|
|
8586
|
-
);
|
|
8587
|
-
if (extract.exitCode !== 0) {
|
|
8588
|
-
throw new Error(`tar extract in box failed: ${asText(extract.stderr).slice(0, 300)}`);
|
|
8589
|
-
}
|
|
8590
|
-
if (finalName !== srcBasename) {
|
|
8591
|
-
const initial = boxParent === "/" ? `/${srcBasename}` : `${boxParent}/${srcBasename}`;
|
|
8592
|
-
const mv = await execa18(
|
|
8593
|
-
"docker",
|
|
8594
|
-
["exec", "--user", "root", box.container, "mv", initial, finalPath],
|
|
8595
|
-
{ reject: false }
|
|
8596
|
-
);
|
|
8597
|
-
if (mv.exitCode !== 0) {
|
|
8598
|
-
throw new Error(
|
|
8599
|
-
`rename ${initial} -> ${finalPath} in box failed: ${asText(mv.stderr).slice(0, 300)}`
|
|
8600
|
-
);
|
|
8601
|
-
}
|
|
8602
|
-
}
|
|
8603
|
-
const chown = await execa18(
|
|
8604
|
-
"docker",
|
|
8605
|
-
["exec", "--user", "root", box.container, "chown", "-R", "1000:1000", finalPath],
|
|
8606
|
-
{ reject: false }
|
|
8607
|
-
);
|
|
8608
|
-
if (chown.exitCode !== 0) {
|
|
8609
|
-
return {
|
|
8610
|
-
finalPath,
|
|
8611
|
-
warn: `chown ${finalPath} to vscode (uid 1000) failed; ownership inside the box may be root.`
|
|
8612
|
-
};
|
|
8613
|
-
}
|
|
8614
|
-
return { finalPath };
|
|
8615
|
-
}
|
|
8616
|
-
async function downloadFromBox(box, boxSrc, hostDst) {
|
|
8617
|
-
const srcBasename = posix.basename(boxSrc);
|
|
8618
|
-
const srcParent = posixDirname(boxSrc);
|
|
8619
|
-
const dstAbs = resolve4(hostDst);
|
|
8620
|
-
let hostParent;
|
|
8621
|
-
let finalName;
|
|
8622
|
-
const dstExists = existsSync3(dstAbs);
|
|
8623
|
-
if (hostDst.endsWith("/") || dstExists && statSync(dstAbs).isDirectory()) {
|
|
8624
|
-
hostParent = dstAbs;
|
|
8625
|
-
finalName = srcBasename;
|
|
8626
|
-
} else {
|
|
8627
|
-
hostParent = dirname22(dstAbs);
|
|
8628
|
-
finalName = basename5(dstAbs);
|
|
8629
|
-
}
|
|
8630
|
-
mkdirSync(hostParent, { recursive: true });
|
|
8631
|
-
const finalPath = posix.join(hostParent, finalName);
|
|
8632
|
-
const packed = await execa18(
|
|
8633
|
-
"docker",
|
|
8634
|
-
["exec", box.container, "tar", "-C", srcParent, "-cf", "-", srcBasename],
|
|
8635
|
-
{ encoding: "buffer", reject: false }
|
|
8636
|
-
);
|
|
8637
|
-
if (packed.exitCode !== 0) {
|
|
8638
|
-
throw new Error(`tar pack in box failed: ${asText(packed.stderr).slice(0, 300)}`);
|
|
8639
|
-
}
|
|
8640
|
-
const extract = await execa18("tar", ["-xf", "-", "-C", hostParent], {
|
|
8641
|
-
input: packed.stdout,
|
|
8642
|
-
reject: false
|
|
8643
|
-
});
|
|
8644
|
-
if (extract.exitCode !== 0) {
|
|
8645
|
-
throw new Error(`tar extract on host failed: ${asText(extract.stderr).slice(0, 300)}`);
|
|
8646
|
-
}
|
|
8647
|
-
if (finalName !== srcBasename) {
|
|
8648
|
-
renameSync(posix.join(hostParent, srcBasename), finalPath);
|
|
8649
|
-
}
|
|
8650
|
-
return { finalPath };
|
|
8651
|
-
}
|
|
8652
8723
|
var dockerProvider = {
|
|
8653
8724
|
name: "docker",
|
|
8654
8725
|
async create(req) {
|
|
@@ -8724,12 +8795,12 @@ var dockerProvider = {
|
|
|
8724
8795
|
const r = await execInBox(box.container, argv, opts?.user ? { user: opts.user } : {});
|
|
8725
8796
|
return { exitCode: r.exitCode, stdout: r.stdout, stderr: r.stderr };
|
|
8726
8797
|
},
|
|
8727
|
-
async uploadPath(box, hostSrc, boxDst) {
|
|
8728
|
-
const r = await uploadToBox(box, hostSrc, boxDst);
|
|
8798
|
+
async uploadPath(box, hostSrc, boxDst, exclude) {
|
|
8799
|
+
const r = await uploadToBox(box, hostSrc, boxDst, exclude);
|
|
8729
8800
|
return { finalPath: r.finalPath };
|
|
8730
8801
|
},
|
|
8731
|
-
async downloadPath(box, boxSrc, hostDst) {
|
|
8732
|
-
const r = await downloadFromBox(box, boxSrc, hostDst);
|
|
8802
|
+
async downloadPath(box, boxSrc, hostDst, exclude) {
|
|
8803
|
+
const r = await downloadFromBox(box, boxSrc, hostDst, exclude);
|
|
8733
8804
|
return { finalPath: r.finalPath };
|
|
8734
8805
|
},
|
|
8735
8806
|
async resolveUrl(box, opts) {
|
|
@@ -8928,6 +8999,7 @@ async function ensureBoxBrowser(container, timeoutMs = 8e3, targetUrl = "about:b
|
|
|
8928
8999
|
}
|
|
8929
9000
|
|
|
8930
9001
|
export {
|
|
9002
|
+
BUILT_IN_DEFAULTS,
|
|
8931
9003
|
KEY_REGISTRY,
|
|
8932
9004
|
lookupKey,
|
|
8933
9005
|
UserConfigError,
|
|
@@ -8974,6 +9046,8 @@ export {
|
|
|
8974
9046
|
execInBox,
|
|
8975
9047
|
removeImage,
|
|
8976
9048
|
volumeExists,
|
|
9049
|
+
uploadToBox,
|
|
9050
|
+
downloadFromBox,
|
|
8977
9051
|
CONTAINER_EXPORT_MERGED,
|
|
8978
9052
|
detectEngine,
|
|
8979
9053
|
setEngineOverride,
|
|
@@ -9174,8 +9248,6 @@ export {
|
|
|
9174
9248
|
allCheckpointImagesBytes,
|
|
9175
9249
|
agentboxHomeBytes,
|
|
9176
9250
|
boxResourceStats,
|
|
9177
|
-
uploadToBox,
|
|
9178
|
-
downloadFromBox,
|
|
9179
9251
|
dockerProvider,
|
|
9180
9252
|
BOX_WORKFLOWS_DIR,
|
|
9181
9253
|
BOX_DYNAMIC_SYNC_MANIFEST,
|
|
@@ -9186,4 +9258,4 @@ export {
|
|
|
9186
9258
|
browserSessionActive,
|
|
9187
9259
|
ensureBoxBrowser
|
|
9188
9260
|
};
|
|
9189
|
-
//# sourceMappingURL=chunk-
|
|
9261
|
+
//# sourceMappingURL=chunk-MLMFNN4T.js.map
|