@madarco/agentbox 0.9.0 → 0.10.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 +89 -0
- package/README.md +161 -0
- package/dist/{_cloud-attach-ZXBCNWJX.js → _cloud-attach-O6NYTLES.js} +3 -3
- package/dist/{chunk-BXQMIEHC.js → chunk-2GPORKYF.js} +254 -162
- package/dist/chunk-2GPORKYF.js.map +1 -0
- package/dist/{chunk-NCJP5MTN.js → chunk-7UIAO7PC.js} +213 -51
- package/dist/chunk-7UIAO7PC.js.map +1 -0
- package/dist/{chunk-GU5LW4B5.js → chunk-R4O5WPHW.js} +374 -62
- package/dist/chunk-R4O5WPHW.js.map +1 -0
- package/dist/{dist-GDHP34ZK.js → dist-5FQGYRW5.js} +15 -3
- package/dist/dist-5FQGYRW5.js.map +1 -0
- package/dist/{dist-32EZBYG4.js → dist-BQNX7RQE.js} +12 -2
- package/dist/{dist-XML54CNB.js → dist-PZW3GWWU.js} +30 -5
- package/dist/dist-PZW3GWWU.js.map +1 -0
- package/dist/{dist-CX5CGVEB.js → dist-TMHSUVTP.js} +3 -3
- package/dist/index.js +1773 -526
- package/dist/index.js.map +1 -1
- package/package.json +9 -7
- package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +9 -8
- package/runtime/docker/packages/ctl/dist/bin.cjs +32 -3
- package/runtime/hetzner/agentbox-setup-skill.md +9 -8
- package/runtime/hetzner/ctl.cjs +32 -3
- package/runtime/relay/bin.cjs +32 -3
- package/runtime/vercel/agentbox-setup-skill.md +9 -8
- package/runtime/vercel/ctl.cjs +32 -3
- package/runtime/vercel/custom-system-CLAUDE.md +1 -4
- package/runtime/vercel/scripts/provision.sh +40 -0
- package/share/agentbox-setup/SKILL.md +9 -8
- package/dist/chunk-BXQMIEHC.js.map +0 -1
- package/dist/chunk-GU5LW4B5.js.map +0 -1
- package/dist/chunk-NCJP5MTN.js.map +0 -1
- package/dist/dist-GDHP34ZK.js.map +0 -1
- package/dist/dist-XML54CNB.js.map +0 -1
- /package/dist/{_cloud-attach-ZXBCNWJX.js.map → _cloud-attach-O6NYTLES.js.map} +0 -0
- /package/dist/{dist-32EZBYG4.js.map → dist-BQNX7RQE.js.map} +0 -0
- /package/dist/{dist-CX5CGVEB.js.map → dist-TMHSUVTP.js.map} +0 -0
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
26
26
|
import { mkdir as mkdir7, stat as stat6 } from "fs/promises";
|
|
27
27
|
import { homedir as homedir9 } from "os";
|
|
28
|
-
import { basename as
|
|
28
|
+
import { basename as basename3, join as join10, resolve as resolve3 } from "path";
|
|
29
29
|
import { execa as execa13 } from "execa";
|
|
30
30
|
|
|
31
31
|
// ../../packages/ctl/dist/index.js
|
|
@@ -758,10 +758,12 @@ var BUILT_IN_DEFAULTS = {
|
|
|
758
758
|
maxLayers: 3
|
|
759
759
|
},
|
|
760
760
|
claude: {
|
|
761
|
-
sessionName: "claude"
|
|
761
|
+
sessionName: "claude",
|
|
762
|
+
dangerouslySkipPermissions: true
|
|
762
763
|
},
|
|
763
764
|
codex: {
|
|
764
|
-
sessionName: "codex"
|
|
765
|
+
sessionName: "codex",
|
|
766
|
+
dangerouslySkipPermissions: true
|
|
765
767
|
},
|
|
766
768
|
opencode: {
|
|
767
769
|
sessionName: "opencode"
|
|
@@ -949,11 +951,21 @@ var KEY_REGISTRY = [
|
|
|
949
951
|
type: "string",
|
|
950
952
|
description: "tmux session name for `agentbox claude`."
|
|
951
953
|
},
|
|
954
|
+
{
|
|
955
|
+
key: "claude.dangerouslySkipPermissions",
|
|
956
|
+
type: "bool",
|
|
957
|
+
description: "Launch claude in new boxes with --dangerously-skip-permissions (auto-accept tool use). Safe because boxes are isolated; on by default. Override per-box with --no-dangerously-skip-permissions."
|
|
958
|
+
},
|
|
952
959
|
{
|
|
953
960
|
key: "codex.sessionName",
|
|
954
961
|
type: "string",
|
|
955
962
|
description: "tmux session name for `agentbox codex`."
|
|
956
963
|
},
|
|
964
|
+
{
|
|
965
|
+
key: "codex.dangerouslySkipPermissions",
|
|
966
|
+
type: "bool",
|
|
967
|
+
description: "Launch codex in new boxes with --dangerously-bypass-approvals-and-sandbox (never prompt for approval). Safe because boxes are isolated; on by default. Override per-box with --no-dangerously-skip-permissions."
|
|
968
|
+
},
|
|
957
969
|
{
|
|
958
970
|
key: "opencode.sessionName",
|
|
959
971
|
type: "string",
|
|
@@ -1637,7 +1649,7 @@ async function touchProjectMeta(absPath) {
|
|
|
1637
1649
|
|
|
1638
1650
|
// ../../packages/sandbox-docker/dist/index.js
|
|
1639
1651
|
import { chmod, mkdir as mkdir32, readFile as readFile32 } from "fs/promises";
|
|
1640
|
-
import { join as join32 } from "path";
|
|
1652
|
+
import { basename as basename2, join as join32 } from "path";
|
|
1641
1653
|
import { execa as execa4 } from "execa";
|
|
1642
1654
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
1643
1655
|
import { stat as stat22 } from "fs/promises";
|
|
@@ -1662,7 +1674,7 @@ import { homedir as homedir6, platform } from "os";
|
|
|
1662
1674
|
import { join as join7, resolve as resolve2 } from "path";
|
|
1663
1675
|
import { mkdir as mkdir5, mkdtemp as mkdtemp2, readFile as readFile5, readdir as readdir32, rm as rm3, writeFile as writeFile22 } from "fs/promises";
|
|
1664
1676
|
import { homedir as homedir7, tmpdir as tmpdir2 } from "os";
|
|
1665
|
-
import { basename as
|
|
1677
|
+
import { basename as basename22, join as join8 } from "path";
|
|
1666
1678
|
import { execa as execa10 } from "execa";
|
|
1667
1679
|
import { stat as stat5 } from "fs/promises";
|
|
1668
1680
|
import { execa as execa11 } from "execa";
|
|
@@ -1670,10 +1682,11 @@ import { execa as execa12 } from "execa";
|
|
|
1670
1682
|
import { spawn } from "child_process";
|
|
1671
1683
|
import { randomBytes as randomBytes22 } from "crypto";
|
|
1672
1684
|
import { existsSync as existsSync2, openSync } from "fs";
|
|
1673
|
-
import { mkdir as mkdir6, readFile as readFile6, unlink as unlink2, writeFile as writeFile32 } from "fs/promises";
|
|
1685
|
+
import { cp, mkdir as mkdir6, readFile as readFile6, readdir as readdir4, rename as rename3, rm as rm4, unlink as unlink2, writeFile as writeFile32 } from "fs/promises";
|
|
1674
1686
|
import { request as httpRequest } from "http";
|
|
1687
|
+
import { createRequire } from "module";
|
|
1675
1688
|
import { homedir as homedir8 } from "os";
|
|
1676
|
-
import { dirname as dirname3, join as join9, resolve as resolve22 } from "path";
|
|
1689
|
+
import { dirname as dirname3, join as join9, resolve as resolve22, sep } from "path";
|
|
1677
1690
|
import { setTimeout as delay2 } from "timers/promises";
|
|
1678
1691
|
import { fileURLToPath } from "url";
|
|
1679
1692
|
|
|
@@ -1864,7 +1877,7 @@ function queueLogPath(id) {
|
|
|
1864
1877
|
|
|
1865
1878
|
// ../../packages/sandbox-docker/dist/index.js
|
|
1866
1879
|
import { execa as execa15 } from "execa";
|
|
1867
|
-
import { readdir as
|
|
1880
|
+
import { readdir as readdir5, rm as rm5, stat as stat7 } from "fs/promises";
|
|
1868
1881
|
import { join as join12 } from "path";
|
|
1869
1882
|
|
|
1870
1883
|
// ../../packages/core/dist/index.js
|
|
@@ -1925,11 +1938,11 @@ import { homedir as homedir10 } from "os";
|
|
|
1925
1938
|
import { join as join13 } from "path";
|
|
1926
1939
|
import { execa as execa16 } from "execa";
|
|
1927
1940
|
import { existsSync as existsSync3, mkdirSync, renameSync, statSync } from "fs";
|
|
1928
|
-
import { basename as
|
|
1941
|
+
import { basename as basename4, dirname as dirname22, posix, resolve as resolve4 } from "path";
|
|
1929
1942
|
import { execa as execa17 } from "execa";
|
|
1930
|
-
import { copyFile, mkdtemp as mkdtemp3, readdir as
|
|
1943
|
+
import { copyFile, mkdtemp as mkdtemp3, readdir as readdir6, readFile as readFile7, rm as rm6, stat as stat8, writeFile as writeFile4 } from "fs/promises";
|
|
1931
1944
|
import { homedir as homedir11, tmpdir as tmpdir3 } from "os";
|
|
1932
|
-
import { basename as
|
|
1945
|
+
import { basename as basename5, join as join14, relative as relative2 } from "path";
|
|
1933
1946
|
import { execa as execa18 } from "execa";
|
|
1934
1947
|
function isHostPathHookCommand(command, hostHome) {
|
|
1935
1948
|
if (typeof command !== "string" || command.length === 0) return false;
|
|
@@ -2728,13 +2741,13 @@ async function copyOneEntry(container, entry) {
|
|
|
2728
2741
|
throw new Error(`mkdir -p ${parentDir} failed: ${String(mkdir8.stderr).slice(0, 300)}`);
|
|
2729
2742
|
}
|
|
2730
2743
|
if (entry.kind === "file") {
|
|
2731
|
-
const
|
|
2744
|
+
const cp2 = await execa22(
|
|
2732
2745
|
"docker",
|
|
2733
2746
|
["cp", entry.absSrc, `${container}:${boxDest}`],
|
|
2734
2747
|
{ reject: false }
|
|
2735
2748
|
);
|
|
2736
|
-
if (
|
|
2737
|
-
throw new Error(`docker cp failed: ${String(
|
|
2749
|
+
if (cp2.exitCode !== 0) {
|
|
2750
|
+
throw new Error(`docker cp failed: ${String(cp2.stderr).slice(0, 300)}`);
|
|
2738
2751
|
}
|
|
2739
2752
|
} else {
|
|
2740
2753
|
const packed = await execa22(
|
|
@@ -3744,6 +3757,54 @@ function isRealAgentCredential(agent, text) {
|
|
|
3744
3757
|
}
|
|
3745
3758
|
return Object.keys(parsed).length > 0;
|
|
3746
3759
|
}
|
|
3760
|
+
async function hostClaudeBackupExpired(path = CREDENTIALS_BACKUP_FILE, now = Date.now()) {
|
|
3761
|
+
try {
|
|
3762
|
+
const parsed = JSON.parse(await readFile32(path, "utf8"));
|
|
3763
|
+
const exp = parsed?.claudeAiOauth?.expiresAt;
|
|
3764
|
+
return typeof exp === "number" && Number.isFinite(exp) && exp < now;
|
|
3765
|
+
} catch {
|
|
3766
|
+
return false;
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
function parseExtractResult(stdout) {
|
|
3770
|
+
return { copied: /\bCOPIED=yes\b/.test(stdout) };
|
|
3771
|
+
}
|
|
3772
|
+
async function extractVolumeAuthToBackup(opts) {
|
|
3773
|
+
try {
|
|
3774
|
+
await mkdir32(STATE_DIR, { recursive: true });
|
|
3775
|
+
const script = 'COPIED=no; if [ -s /dst/auth.json ]; then cp -a /dst/auth.json "/host-state/$DEST" && COPIED=yes; fi; echo "COPIED=$COPIED"';
|
|
3776
|
+
const { stdout } = await execa4("docker", [
|
|
3777
|
+
"run",
|
|
3778
|
+
"--rm",
|
|
3779
|
+
"--user",
|
|
3780
|
+
"0",
|
|
3781
|
+
"-v",
|
|
3782
|
+
`${opts.volume}:/dst`,
|
|
3783
|
+
"-v",
|
|
3784
|
+
`${STATE_DIR}:/host-state`,
|
|
3785
|
+
"-e",
|
|
3786
|
+
// Pass the destination filename via env so the path isn't interpolated
|
|
3787
|
+
// into the script string (keeps the docker arg list static + injection-safe).
|
|
3788
|
+
`DEST=${basename2(opts.backupFile)}`,
|
|
3789
|
+
opts.image,
|
|
3790
|
+
"sh",
|
|
3791
|
+
"-c",
|
|
3792
|
+
script
|
|
3793
|
+
]);
|
|
3794
|
+
const result = parseExtractResult(stdout);
|
|
3795
|
+
if (result.copied) await chmod(opts.backupFile, 384).catch(() => {
|
|
3796
|
+
});
|
|
3797
|
+
return result;
|
|
3798
|
+
} catch {
|
|
3799
|
+
return { copied: false };
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3802
|
+
function extractCodexCredentials(volume, image) {
|
|
3803
|
+
return extractVolumeAuthToBackup({ volume, image, backupFile: CODEX_CREDENTIALS_BACKUP_FILE });
|
|
3804
|
+
}
|
|
3805
|
+
function extractOpencodeCredentials(volume, image) {
|
|
3806
|
+
return extractVolumeAuthToBackup({ volume, image, backupFile: OPENCODE_CREDENTIALS_BACKUP_FILE });
|
|
3807
|
+
}
|
|
3747
3808
|
async function hostBackupHasCredentials(path = CREDENTIALS_BACKUP_FILE) {
|
|
3748
3809
|
try {
|
|
3749
3810
|
const parsed = JSON.parse(await readFile32(path, "utf8"));
|
|
@@ -4998,7 +5059,7 @@ async function createSnapshot(opts) {
|
|
|
4998
5059
|
var CHECKPOINTS_ROOT = join8(homedir7(), ".agentbox", "checkpoints");
|
|
4999
5060
|
var CHECKPOINT_IMAGE_PREFIX = "agentbox-ckpt-";
|
|
5000
5061
|
function checkpointImageTag(projectRoot, name) {
|
|
5001
|
-
const mnemonic = sanitizeMnemonic(
|
|
5062
|
+
const mnemonic = sanitizeMnemonic(basename22(projectRoot));
|
|
5002
5063
|
return `${CHECKPOINT_IMAGE_PREFIX}${hashProjectPath(projectRoot)}_${mnemonic}:${name}`;
|
|
5003
5064
|
}
|
|
5004
5065
|
function projectCheckpointsDir(projectRoot) {
|
|
@@ -5348,6 +5409,7 @@ async function ensureHomeOwnedByVscode(container) {
|
|
|
5348
5409
|
var STATE_DIR22 = join9(homedir8(), ".agentbox");
|
|
5349
5410
|
var PID_FILE = join9(STATE_DIR22, "relay.pid");
|
|
5350
5411
|
var LOG_FILE = join9(STATE_DIR22, "relay.log");
|
|
5412
|
+
var RELAY_HOME_DIR = join9(STATE_DIR22, "relay");
|
|
5351
5413
|
var PORT = DEFAULT_RELAY_PORT;
|
|
5352
5414
|
var ENDPOINT = {
|
|
5353
5415
|
// host.docker.internal is the Docker Desktop / OrbStack-supplied alias for
|
|
@@ -5358,6 +5420,13 @@ var ENDPOINT = {
|
|
|
5358
5420
|
hostUrl: `http://127.0.0.1:${String(PORT)}`,
|
|
5359
5421
|
port: PORT
|
|
5360
5422
|
};
|
|
5423
|
+
function shouldReclaimForVersion(health, currentVersion) {
|
|
5424
|
+
if (health.cliEntry === false) return true;
|
|
5425
|
+
if (typeof health.version === "string" && health.version.length > 0 && typeof currentVersion === "string" && currentVersion.length > 0 && health.version !== currentVersion) {
|
|
5426
|
+
return true;
|
|
5427
|
+
}
|
|
5428
|
+
return false;
|
|
5429
|
+
}
|
|
5361
5430
|
async function ensureRelay(opts = {}) {
|
|
5362
5431
|
const log = opts.onLog ?? (() => {
|
|
5363
5432
|
});
|
|
@@ -5366,12 +5435,19 @@ async function ensureRelay(opts = {}) {
|
|
|
5366
5435
|
await removeContainer(RELAY_CONTAINER_NAME);
|
|
5367
5436
|
log(`removed legacy relay container ${RELAY_CONTAINER_NAME}`);
|
|
5368
5437
|
}
|
|
5438
|
+
const currentVersion = process.env.AGENTBOX_CLI_VERSION;
|
|
5369
5439
|
const health = await fetchHealthz(500);
|
|
5370
5440
|
if (health !== null) {
|
|
5371
|
-
if (health
|
|
5441
|
+
if (!shouldReclaimForVersion(health, currentVersion)) {
|
|
5372
5442
|
return ENDPOINT;
|
|
5373
5443
|
}
|
|
5374
|
-
|
|
5444
|
+
if (health.cliEntry === false) {
|
|
5445
|
+
log("relay is alive but lacks AGENTBOX_CLI_ENTRY (cp/download/checkpoint would fail) \u2014 reclaiming");
|
|
5446
|
+
} else {
|
|
5447
|
+
log(
|
|
5448
|
+
`relay was spawned by agentbox ${health.version ?? "?"} but this CLI is ${currentVersion ?? "?"} \u2014 reclaiming to keep the relay version-consistent`
|
|
5449
|
+
);
|
|
5450
|
+
}
|
|
5375
5451
|
await reclaimRelay(health.pid, log);
|
|
5376
5452
|
} else {
|
|
5377
5453
|
const existingPid = await readPidFile();
|
|
@@ -5388,8 +5464,9 @@ async function ensureRelay(opts = {}) {
|
|
|
5388
5464
|
});
|
|
5389
5465
|
}
|
|
5390
5466
|
}
|
|
5391
|
-
const
|
|
5392
|
-
const
|
|
5467
|
+
const staged = await stageRelayHome(currentVersion ?? "", log).catch(() => null);
|
|
5468
|
+
const relayBin = staged?.relayBin ?? resolveRelayBin();
|
|
5469
|
+
const cliEntry = staged?.cliEntry ?? resolveCliEntry();
|
|
5393
5470
|
if (cliEntry === null) {
|
|
5394
5471
|
throw new Error(
|
|
5395
5472
|
"cannot start the host relay: agentbox CLI entry not found (is the build complete / dist present?). Set AGENTBOX_CLI_ENTRY to override."
|
|
@@ -5411,7 +5488,7 @@ async function reclaimRelay(reportedPid, log) {
|
|
|
5411
5488
|
});
|
|
5412
5489
|
if (await pingHealthz(300)) {
|
|
5413
5490
|
throw new Error(
|
|
5414
|
-
`a relay
|
|
5491
|
+
`a relay is still listening on :${String(PORT)} and could not be stopped (reported pid ${String(reportedPid ?? "unknown")}); kill it manually and retry`
|
|
5415
5492
|
);
|
|
5416
5493
|
}
|
|
5417
5494
|
}
|
|
@@ -5494,6 +5571,80 @@ function resolveCliEntry() {
|
|
|
5494
5571
|
}
|
|
5495
5572
|
return null;
|
|
5496
5573
|
}
|
|
5574
|
+
async function stageRelayHome(version, log) {
|
|
5575
|
+
if (!version || version === "0.0.0-dev") return null;
|
|
5576
|
+
if (process.env.AGENTBOX_RELAY_BIN || process.env.AGENTBOX_CLI_ENTRY) return null;
|
|
5577
|
+
const cliRoot = findCliRoot(dirname3(fileURLToPath(import.meta.url)));
|
|
5578
|
+
if (cliRoot === null) return null;
|
|
5579
|
+
const homeDir = join9(RELAY_HOME_DIR, version);
|
|
5580
|
+
const stagedEntry = join9(homeDir, "dist", "index.js");
|
|
5581
|
+
const stagedBin = join9(homeDir, "runtime", "relay", "bin.cjs");
|
|
5582
|
+
if (existsSync2(stagedEntry) && existsSync2(stagedBin)) {
|
|
5583
|
+
return { relayBin: stagedBin, cliEntry: stagedEntry };
|
|
5584
|
+
}
|
|
5585
|
+
const nodeModules = resolveDepRoot(join9(cliRoot, "dist", "index.js"));
|
|
5586
|
+
if (nodeModules === null) return null;
|
|
5587
|
+
const tmpDir = `${homeDir}.tmp-${String(process.pid)}`;
|
|
5588
|
+
try {
|
|
5589
|
+
await mkdir6(RELAY_HOME_DIR, { recursive: true });
|
|
5590
|
+
await rm4(tmpDir, { recursive: true, force: true });
|
|
5591
|
+
await mkdir6(tmpDir, { recursive: true });
|
|
5592
|
+
for (const sub of ["dist", "runtime", "share"]) {
|
|
5593
|
+
const src = join9(cliRoot, sub);
|
|
5594
|
+
if (existsSync2(src)) await cp(src, join9(tmpDir, sub), { recursive: true });
|
|
5595
|
+
}
|
|
5596
|
+
await cp(nodeModules, join9(tmpDir, "node_modules"), { recursive: true, dereference: true });
|
|
5597
|
+
await rm4(homeDir, { recursive: true, force: true });
|
|
5598
|
+
await rename3(tmpDir, homeDir);
|
|
5599
|
+
} catch (err) {
|
|
5600
|
+
await rm4(tmpDir, { recursive: true, force: true }).catch(() => {
|
|
5601
|
+
});
|
|
5602
|
+
if (existsSync2(stagedEntry) && existsSync2(stagedBin)) {
|
|
5603
|
+
return { relayBin: stagedBin, cliEntry: stagedEntry };
|
|
5604
|
+
}
|
|
5605
|
+
log(`relay home staging failed (${err instanceof Error ? err.message : String(err)}); using bundle paths`);
|
|
5606
|
+
return null;
|
|
5607
|
+
}
|
|
5608
|
+
log(`staged relay home for ${version} at ${homeDir}`);
|
|
5609
|
+
await gcOldRelayHomes(version).catch(() => {
|
|
5610
|
+
});
|
|
5611
|
+
return { relayBin: stagedBin, cliEntry: stagedEntry };
|
|
5612
|
+
}
|
|
5613
|
+
function findCliRoot(moduleDir) {
|
|
5614
|
+
for (const root of [resolve22(moduleDir, ".."), resolve22(moduleDir, "..", "..")]) {
|
|
5615
|
+
if (existsSync2(join9(root, "dist", "index.js")) && existsSync2(join9(root, "runtime", "relay", "bin.cjs"))) {
|
|
5616
|
+
return root;
|
|
5617
|
+
}
|
|
5618
|
+
}
|
|
5619
|
+
return null;
|
|
5620
|
+
}
|
|
5621
|
+
function resolveDepRoot(fromFile) {
|
|
5622
|
+
try {
|
|
5623
|
+
const req = createRequire(fromFile);
|
|
5624
|
+
const main = req.resolve("commander");
|
|
5625
|
+
if (main.includes(`${sep}.pnpm${sep}`)) return null;
|
|
5626
|
+
const marker = `${sep}node_modules${sep}`;
|
|
5627
|
+
const idx = main.lastIndexOf(marker);
|
|
5628
|
+
if (idx === -1) return null;
|
|
5629
|
+
const nm = main.slice(0, idx + marker.length - 1);
|
|
5630
|
+
return existsSync2(join9(nm, "commander")) ? nm : null;
|
|
5631
|
+
} catch {
|
|
5632
|
+
return null;
|
|
5633
|
+
}
|
|
5634
|
+
}
|
|
5635
|
+
async function gcOldRelayHomes(keepVersion) {
|
|
5636
|
+
let entries;
|
|
5637
|
+
try {
|
|
5638
|
+
entries = await readdir4(RELAY_HOME_DIR);
|
|
5639
|
+
} catch {
|
|
5640
|
+
return;
|
|
5641
|
+
}
|
|
5642
|
+
for (const name of entries) {
|
|
5643
|
+
if (name === keepVersion) continue;
|
|
5644
|
+
await rm4(join9(RELAY_HOME_DIR, name), { recursive: true, force: true }).catch(() => {
|
|
5645
|
+
});
|
|
5646
|
+
}
|
|
5647
|
+
}
|
|
5497
5648
|
async function stopRelay() {
|
|
5498
5649
|
const pid = await readPidFile();
|
|
5499
5650
|
if (pid === null) {
|
|
@@ -5532,7 +5683,7 @@ async function getRelayStatus() {
|
|
|
5532
5683
|
pidAlive: pidAlive2,
|
|
5533
5684
|
port: PORT,
|
|
5534
5685
|
endpoint: ENDPOINT,
|
|
5535
|
-
health: health === null ? null : { boxes: health.boxes, events: health.events },
|
|
5686
|
+
health: health === null ? null : { boxes: health.boxes, events: health.events, version: health.version, commit: health.commit },
|
|
5536
5687
|
pidFile: PID_FILE,
|
|
5537
5688
|
logFile: LOG_FILE
|
|
5538
5689
|
};
|
|
@@ -5577,7 +5728,9 @@ function fetchHealthz(timeoutMs) {
|
|
|
5577
5728
|
boxes: parsed.boxes,
|
|
5578
5729
|
events: parsed.events,
|
|
5579
5730
|
pid: typeof parsed.pid === "number" ? parsed.pid : void 0,
|
|
5580
|
-
cliEntry: typeof parsed.cliEntry === "boolean" ? parsed.cliEntry : void 0
|
|
5731
|
+
cliEntry: typeof parsed.cliEntry === "boolean" ? parsed.cliEntry : void 0,
|
|
5732
|
+
version: typeof parsed.version === "string" && parsed.version.length > 0 ? parsed.version : void 0,
|
|
5733
|
+
commit: typeof parsed.commit === "string" && parsed.commit.length > 0 ? parsed.commit : void 0
|
|
5581
5734
|
});
|
|
5582
5735
|
} else {
|
|
5583
5736
|
resolveP(null);
|
|
@@ -5930,7 +6083,7 @@ function generateBoxId() {
|
|
|
5930
6083
|
return randomBytes3(4).toString("hex");
|
|
5931
6084
|
}
|
|
5932
6085
|
function sanitizeBasename(workspacePath) {
|
|
5933
|
-
const raw =
|
|
6086
|
+
const raw = basename3(resolve3(workspacePath));
|
|
5934
6087
|
return raw.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^[-._]+|[-._]+$/g, "").slice(0, 30).replace(/[-._]+$/, "");
|
|
5935
6088
|
}
|
|
5936
6089
|
function defaultBoxName(workspacePath, id) {
|
|
@@ -6771,10 +6924,11 @@ async function listBoxes() {
|
|
|
6771
6924
|
};
|
|
6772
6925
|
return {
|
|
6773
6926
|
...b,
|
|
6774
|
-
state: "running",
|
|
6927
|
+
state: b.cloud?.lastState ?? "running",
|
|
6775
6928
|
endpoints: endpoints2,
|
|
6776
6929
|
claudeActivity: persisted2?.claude.state,
|
|
6777
6930
|
claudeSessionTitle: persisted2?.claude.sessionTitle,
|
|
6931
|
+
claudeQuestion: persisted2?.claude.state === "question" ? persisted2.claude.question : void 0,
|
|
6778
6932
|
codexActivity: persisted2?.codex?.state,
|
|
6779
6933
|
codexSessionTitle: persisted2?.codex?.sessionTitle,
|
|
6780
6934
|
opencodeSessionTitle: persisted2?.opencode?.sessionTitle,
|
|
@@ -6795,6 +6949,7 @@ async function listBoxes() {
|
|
|
6795
6949
|
endpoints,
|
|
6796
6950
|
claudeActivity: persisted?.claude.state,
|
|
6797
6951
|
claudeSessionTitle: persisted?.claude.sessionTitle,
|
|
6952
|
+
claudeQuestion: persisted?.claude.state === "question" ? persisted.claude.question : void 0,
|
|
6798
6953
|
codexActivity: persisted?.codex?.state,
|
|
6799
6954
|
codexSessionTitle: persisted?.codex?.sessionTitle,
|
|
6800
6955
|
opencodeSessionTitle: persisted?.opencode?.sessionTitle,
|
|
@@ -7065,14 +7220,14 @@ async function destroyBox(idOrName, opts = {}) {
|
|
|
7065
7220
|
let removedSnapshot = null;
|
|
7066
7221
|
if (box.snapshotDir && !opts.keepSnapshot) {
|
|
7067
7222
|
try {
|
|
7068
|
-
await
|
|
7223
|
+
await rm5(box.snapshotDir, { recursive: true, force: true });
|
|
7069
7224
|
removedSnapshot = box.snapshotDir;
|
|
7070
7225
|
} catch {
|
|
7071
7226
|
removedSnapshot = null;
|
|
7072
7227
|
}
|
|
7073
7228
|
}
|
|
7074
7229
|
try {
|
|
7075
|
-
await
|
|
7230
|
+
await rm5(boxRunDirFor(box), { recursive: true, force: true });
|
|
7076
7231
|
} catch {
|
|
7077
7232
|
}
|
|
7078
7233
|
await removeBoxRecord(box.id);
|
|
@@ -7080,7 +7235,7 @@ async function destroyBox(idOrName, opts = {}) {
|
|
|
7080
7235
|
}
|
|
7081
7236
|
async function listSnapshotDirs() {
|
|
7082
7237
|
try {
|
|
7083
|
-
const entries = await
|
|
7238
|
+
const entries = await readdir5(SNAPSHOTS_ROOT, { withFileTypes: true });
|
|
7084
7239
|
return entries.filter((e) => e.isDirectory()).map((e) => join12(SNAPSHOTS_ROOT, e.name));
|
|
7085
7240
|
} catch {
|
|
7086
7241
|
return [];
|
|
@@ -7088,7 +7243,7 @@ async function listSnapshotDirs() {
|
|
|
7088
7243
|
}
|
|
7089
7244
|
async function listBoxDirs() {
|
|
7090
7245
|
try {
|
|
7091
|
-
const entries = await
|
|
7246
|
+
const entries = await readdir5(BOXES_ROOT, { withFileTypes: true });
|
|
7092
7247
|
return entries.filter((e) => e.isDirectory()).map((e) => join12(BOXES_ROOT, e.name));
|
|
7093
7248
|
} catch {
|
|
7094
7249
|
return [];
|
|
@@ -7184,13 +7339,13 @@ async function pruneBoxes(opts = {}) {
|
|
|
7184
7339
|
for (const v of orphanVolumes) await removeVolume(v);
|
|
7185
7340
|
for (const d of orphanSnapshots) {
|
|
7186
7341
|
try {
|
|
7187
|
-
await
|
|
7342
|
+
await rm5(d, { recursive: true, force: true });
|
|
7188
7343
|
} catch {
|
|
7189
7344
|
}
|
|
7190
7345
|
}
|
|
7191
7346
|
for (const d of orphanBoxDirs) {
|
|
7192
7347
|
try {
|
|
7193
|
-
await
|
|
7348
|
+
await rm5(d, { recursive: true, force: true });
|
|
7194
7349
|
} catch {
|
|
7195
7350
|
}
|
|
7196
7351
|
}
|
|
@@ -7455,7 +7610,7 @@ function asText(s) {
|
|
|
7455
7610
|
async function uploadToBox(box, hostSrc, boxDst) {
|
|
7456
7611
|
const srcAbs = resolve4(hostSrc);
|
|
7457
7612
|
if (!existsSync3(srcAbs)) throw new Error(`source not found: ${hostSrc}`);
|
|
7458
|
-
const srcBasename =
|
|
7613
|
+
const srcBasename = basename4(srcAbs);
|
|
7459
7614
|
const srcParent = dirname22(srcAbs);
|
|
7460
7615
|
let boxParent;
|
|
7461
7616
|
let finalName;
|
|
@@ -7539,7 +7694,7 @@ async function downloadFromBox(box, boxSrc, hostDst) {
|
|
|
7539
7694
|
finalName = srcBasename;
|
|
7540
7695
|
} else {
|
|
7541
7696
|
hostParent = dirname22(dstAbs);
|
|
7542
|
-
finalName =
|
|
7697
|
+
finalName = basename4(dstAbs);
|
|
7543
7698
|
}
|
|
7544
7699
|
mkdirSync(hostParent, { recursive: true });
|
|
7545
7700
|
const finalPath = posix.join(hostParent, finalName);
|
|
@@ -7708,7 +7863,7 @@ async function findBrokenSymlinks2(root) {
|
|
|
7708
7863
|
async function walk(dir) {
|
|
7709
7864
|
let entries;
|
|
7710
7865
|
try {
|
|
7711
|
-
entries = await
|
|
7866
|
+
entries = await readdir6(dir, { withFileTypes: true });
|
|
7712
7867
|
} catch {
|
|
7713
7868
|
return;
|
|
7714
7869
|
}
|
|
@@ -7736,7 +7891,7 @@ function emptyResult(warnings = []) {
|
|
|
7736
7891
|
}, warnings };
|
|
7737
7892
|
}
|
|
7738
7893
|
async function tarballFromDir(stageDir, agent) {
|
|
7739
|
-
const tarballPath = join14(tmpdir3(), `agentbox-${agent}-${
|
|
7894
|
+
const tarballPath = join14(tmpdir3(), `agentbox-${agent}-${basename5(stageDir)}.tar.gz`);
|
|
7740
7895
|
await execa18("tar", ["-czf", tarballPath, "-C", stageDir, "."], {
|
|
7741
7896
|
env: { ...process.env, COPYFILE_DISABLE: "1" }
|
|
7742
7897
|
});
|
|
@@ -7745,7 +7900,7 @@ async function tarballFromDir(stageDir, agent) {
|
|
|
7745
7900
|
function makeCleanup(paths) {
|
|
7746
7901
|
return async () => {
|
|
7747
7902
|
for (const p of paths) {
|
|
7748
|
-
await
|
|
7903
|
+
await rm6(p, { recursive: true, force: true });
|
|
7749
7904
|
}
|
|
7750
7905
|
};
|
|
7751
7906
|
}
|
|
@@ -7761,8 +7916,8 @@ async function stageSingleFileTarball(agent, sourcePath, tarballEntryName) {
|
|
|
7761
7916
|
warnings: []
|
|
7762
7917
|
};
|
|
7763
7918
|
} catch (err) {
|
|
7764
|
-
await
|
|
7765
|
-
if (tarballPath) await
|
|
7919
|
+
await rm6(stageDir, { recursive: true, force: true });
|
|
7920
|
+
if (tarballPath) await rm6(tarballPath, { force: true });
|
|
7766
7921
|
throw err;
|
|
7767
7922
|
}
|
|
7768
7923
|
}
|
|
@@ -7845,7 +8000,7 @@ async function stageClaudeStaticForUpload(opts = {}) {
|
|
|
7845
8000
|
const pluginsDir = join14(stageDir, "plugins");
|
|
7846
8001
|
if (await pathExists7(pluginsDir)) {
|
|
7847
8002
|
try {
|
|
7848
|
-
const entries = await
|
|
8003
|
+
const entries = await readdir6(pluginsDir, { withFileTypes: true });
|
|
7849
8004
|
for (const ent of entries) {
|
|
7850
8005
|
if (!ent.isFile() || !ent.name.endsWith(".json")) continue;
|
|
7851
8006
|
const file = join14(pluginsDir, ent.name);
|
|
@@ -7863,8 +8018,8 @@ async function stageClaudeStaticForUpload(opts = {}) {
|
|
|
7863
8018
|
warnings: []
|
|
7864
8019
|
};
|
|
7865
8020
|
} catch (err) {
|
|
7866
|
-
await
|
|
7867
|
-
if (tarballPath) await
|
|
8021
|
+
await rm6(stageDir, { recursive: true, force: true });
|
|
8022
|
+
if (tarballPath) await rm6(tarballPath, { force: true });
|
|
7868
8023
|
throw err;
|
|
7869
8024
|
}
|
|
7870
8025
|
}
|
|
@@ -7924,16 +8079,17 @@ async function stageCodexStaticForUpload(opts = {}) {
|
|
|
7924
8079
|
warnings: []
|
|
7925
8080
|
};
|
|
7926
8081
|
} catch (err) {
|
|
7927
|
-
await
|
|
7928
|
-
if (tarballPath) await
|
|
8082
|
+
await rm6(stageDir, { recursive: true, force: true });
|
|
8083
|
+
if (tarballPath) await rm6(tarballPath, { force: true });
|
|
7929
8084
|
throw err;
|
|
7930
8085
|
}
|
|
7931
8086
|
}
|
|
7932
8087
|
async function stageCodexCredentialsForUpload(opts = {}) {
|
|
7933
|
-
if (await pathExists7(CODEX_CREDENTIALS_BACKUP_FILE)) {
|
|
7934
|
-
return stageSingleFileTarball("codex-creds", CODEX_CREDENTIALS_BACKUP_FILE, "auth.json");
|
|
7935
|
-
}
|
|
7936
8088
|
const hostHome = opts.hostHome ?? homedir11();
|
|
8089
|
+
const cloudBackup = join14(hostHome, ".agentbox", "codex-credentials.json");
|
|
8090
|
+
if (await pathExists7(cloudBackup)) {
|
|
8091
|
+
return stageSingleFileTarball("codex-creds", cloudBackup, "auth.json");
|
|
8092
|
+
}
|
|
7937
8093
|
const hostAuth = join14(hostHome, ".codex", "auth.json");
|
|
7938
8094
|
if (!await pathExists7(hostAuth)) return emptyResult([CODEX_KEYCHAIN_WARNING]);
|
|
7939
8095
|
return stageSingleFileTarball("codex-creds", hostAuth, "auth.json");
|
|
@@ -7991,16 +8147,17 @@ async function stageOpencodeStaticForUpload(opts = {}) {
|
|
|
7991
8147
|
warnings: []
|
|
7992
8148
|
};
|
|
7993
8149
|
} catch (err) {
|
|
7994
|
-
await
|
|
7995
|
-
if (tarballPath) await
|
|
8150
|
+
await rm6(stageDir, { recursive: true, force: true });
|
|
8151
|
+
if (tarballPath) await rm6(tarballPath, { force: true });
|
|
7996
8152
|
throw err;
|
|
7997
8153
|
}
|
|
7998
8154
|
}
|
|
7999
8155
|
async function stageOpencodeCredentialsForUpload(opts = {}) {
|
|
8000
|
-
if (await pathExists7(OPENCODE_CREDENTIALS_BACKUP_FILE)) {
|
|
8001
|
-
return stageSingleFileTarball("opencode-creds", OPENCODE_CREDENTIALS_BACKUP_FILE, "auth.json");
|
|
8002
|
-
}
|
|
8003
8156
|
const hostHome = opts.hostHome ?? homedir11();
|
|
8157
|
+
const cloudBackup = join14(hostHome, ".agentbox", "opencode-credentials.json");
|
|
8158
|
+
if (await pathExists7(cloudBackup)) {
|
|
8159
|
+
return stageSingleFileTarball("opencode-creds", cloudBackup, "auth.json");
|
|
8160
|
+
}
|
|
8004
8161
|
const hostAuth = join14(hostHome, ".local", "share", "opencode", "auth.json");
|
|
8005
8162
|
if (!await pathExists7(hostAuth)) return emptyResult();
|
|
8006
8163
|
return stageSingleFileTarball("opencode-creds", hostAuth, "auth.json");
|
|
@@ -8123,6 +8280,11 @@ export {
|
|
|
8123
8280
|
CODEX_CREDENTIALS_BACKUP_FILE,
|
|
8124
8281
|
OPENCODE_CREDENTIALS_BACKUP_FILE,
|
|
8125
8282
|
isRealAgentCredential,
|
|
8283
|
+
hostClaudeBackupExpired,
|
|
8284
|
+
parseExtractResult,
|
|
8285
|
+
extractVolumeAuthToBackup,
|
|
8286
|
+
extractCodexCredentials,
|
|
8287
|
+
extractOpencodeCredentials,
|
|
8126
8288
|
hostBackupHasCredentials,
|
|
8127
8289
|
parseSyncResult,
|
|
8128
8290
|
syncClaudeCredentials,
|
|
@@ -8268,4 +8430,4 @@ export {
|
|
|
8268
8430
|
browserSessionActive,
|
|
8269
8431
|
ensureBoxBrowser
|
|
8270
8432
|
};
|
|
8271
|
-
//# sourceMappingURL=chunk-
|
|
8433
|
+
//# sourceMappingURL=chunk-7UIAO7PC.js.map
|