@madarco/agentbox 0.13.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 +125 -0
- package/README.md +11 -8
- package/dist/{_cloud-attach-HJC672UR.js → _cloud-attach-R6TRWG5L.js} +4 -4
- package/dist/{chunk-QYRK5H6Q.js → chunk-43Q5GWP6.js} +108 -56
- package/dist/chunk-43Q5GWP6.js.map +1 -0
- package/dist/{chunk-ECLLV5JH.js → chunk-72CJTXN6.js} +156 -5
- package/dist/chunk-72CJTXN6.js.map +1 -0
- package/dist/{chunk-R5XIDQFR.js → chunk-BKU34KYY.js} +170 -6
- package/dist/chunk-BKU34KYY.js.map +1 -0
- package/dist/{chunk-4NQXNQ53.js → chunk-E7CHS7ZR.js} +168 -58
- package/dist/chunk-E7CHS7ZR.js.map +1 -0
- package/dist/chunk-MCOU6CZS.js +346 -0
- package/dist/chunk-MCOU6CZS.js.map +1 -0
- package/dist/{chunk-B4QG2MCW.js → chunk-MLMFNN4T.js} +762 -483
- package/dist/chunk-MLMFNN4T.js.map +1 -0
- package/dist/{chunk-2LF5YILI.js → chunk-RSKG7AFU.js} +80 -6
- package/dist/chunk-RSKG7AFU.js.map +1 -0
- package/dist/{chunk-SNTHHWKY.js → chunk-XKH7NTT7.js} +80 -22
- package/dist/chunk-XKH7NTT7.js.map +1 -0
- package/dist/{dist-7KVUIKJX.js → dist-AGTIA7AD.js} +37 -226
- package/dist/dist-AGTIA7AD.js.map +1 -0
- package/dist/{dist-OPIBZ7XM.js → dist-FIFEFKJ7.js} +14 -69
- package/dist/dist-FIFEFKJ7.js.map +1 -0
- package/dist/dist-JZ3XO6EB.js +662 -0
- package/dist/dist-JZ3XO6EB.js.map +1 -0
- package/dist/{dist-OG6NW6SM.js → dist-OGJGZETZ.js} +5 -3
- package/dist/{dist-JAN5VABY.js → dist-S4XR4ACV.js} +25 -177
- package/dist/dist-S4XR4ACV.js.map +1 -0
- package/dist/index.js +2229 -1314
- package/dist/index.js.map +1 -1
- package/dist/{prepared-state-MQHD3M5F-KE4DT3GX.js → prepared-state-MQHD3M5F-Q27AZU53.js} +2 -2
- package/package.json +6 -4
- package/runtime/docker/Dockerfile.box +21 -26
- package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +67 -1
- package/runtime/docker/packages/ctl/dist/bin.cjs +361 -43
- package/runtime/docker/packages/sandbox-docker/scripts/agentbox-vnc-start +17 -6
- package/runtime/docker/packages/sandbox-docker/scripts/chromium-resolver +57 -0
- package/runtime/docker/packages/sandbox-docker/scripts/claude-managed-settings.json +2 -1
- package/runtime/e2b/agentbox-checkpoint-cleanup +52 -0
- package/runtime/e2b/agentbox-codex-hooks.json +68 -0
- package/runtime/e2b/agentbox-open +28 -0
- package/runtime/e2b/agentbox-setup-skill.md +263 -0
- package/runtime/e2b/agentbox-vnc-start +102 -0
- package/runtime/e2b/attach-helper.cjs +167 -0
- package/runtime/e2b/claude-managed-settings.json +116 -0
- package/runtime/e2b/ctl.cjs +24158 -0
- package/runtime/e2b/custom-system-CLAUDE.md +46 -0
- package/runtime/e2b/gh-shim +344 -0
- package/runtime/e2b/git-shim +131 -0
- package/runtime/e2b/scripts/build-template.sh +295 -0
- package/runtime/hetzner/agentbox-setup-skill.md +67 -1
- package/runtime/hetzner/agentbox-vnc-start +17 -6
- package/runtime/hetzner/claude-managed-settings.json +2 -1
- package/runtime/hetzner/ctl.cjs +361 -43
- package/runtime/relay/bin.cjs +380 -233
- package/runtime/vercel/agentbox-setup-skill.md +67 -1
- package/runtime/vercel/agentbox-vnc-start +17 -6
- package/runtime/vercel/claude-managed-settings.json +2 -1
- package/runtime/vercel/ctl.cjs +361 -43
- package/share/agentbox-setup/SKILL.md +67 -1
- package/share/host-skills/agentbox-info/SKILL.md +47 -35
- package/dist/chunk-2LF5YILI.js.map +0 -1
- package/dist/chunk-4NQXNQ53.js.map +0 -1
- package/dist/chunk-B4QG2MCW.js.map +0 -1
- package/dist/chunk-ECLLV5JH.js.map +0 -1
- package/dist/chunk-QYRK5H6Q.js.map +0 -1
- package/dist/chunk-R5XIDQFR.js.map +0 -1
- package/dist/chunk-SNTHHWKY.js.map +0 -1
- package/dist/dist-7KVUIKJX.js.map +0 -1
- package/dist/dist-JAN5VABY.js.map +0 -1
- package/dist/dist-OPIBZ7XM.js.map +0 -1
- /package/dist/{_cloud-attach-HJC672UR.js.map → _cloud-attach-R6TRWG5L.js.map} +0 -0
- /package/dist/{dist-OG6NW6SM.js.map → dist-OGJGZETZ.js.map} +0 -0
- /package/dist/{prepared-state-MQHD3M5F-KE4DT3GX.js.map → prepared-state-MQHD3M5F-Q27AZU53.js.map} +0 -0
package/runtime/hetzner/ctl.cjs
CHANGED
|
@@ -3344,15 +3344,15 @@ var require_windows = __commonJS({
|
|
|
3344
3344
|
}
|
|
3345
3345
|
return false;
|
|
3346
3346
|
}
|
|
3347
|
-
function checkStat(
|
|
3348
|
-
if (!
|
|
3347
|
+
function checkStat(stat3, path6, options) {
|
|
3348
|
+
if (!stat3.isSymbolicLink() && !stat3.isFile()) {
|
|
3349
3349
|
return false;
|
|
3350
3350
|
}
|
|
3351
3351
|
return checkPathExt(path6, options);
|
|
3352
3352
|
}
|
|
3353
3353
|
function isexe(path6, options, cb) {
|
|
3354
|
-
fs.stat(path6, function(er,
|
|
3355
|
-
cb(er, er ? false : checkStat(
|
|
3354
|
+
fs.stat(path6, function(er, stat3) {
|
|
3355
|
+
cb(er, er ? false : checkStat(stat3, path6, options));
|
|
3356
3356
|
});
|
|
3357
3357
|
}
|
|
3358
3358
|
function sync(path6, options) {
|
|
@@ -3369,20 +3369,20 @@ var require_mode = __commonJS({
|
|
|
3369
3369
|
isexe.sync = sync;
|
|
3370
3370
|
var fs = require("fs");
|
|
3371
3371
|
function isexe(path6, options, cb) {
|
|
3372
|
-
fs.stat(path6, function(er,
|
|
3373
|
-
cb(er, er ? false : checkStat(
|
|
3372
|
+
fs.stat(path6, function(er, stat3) {
|
|
3373
|
+
cb(er, er ? false : checkStat(stat3, options));
|
|
3374
3374
|
});
|
|
3375
3375
|
}
|
|
3376
3376
|
function sync(path6, options) {
|
|
3377
3377
|
return checkStat(fs.statSync(path6), options);
|
|
3378
3378
|
}
|
|
3379
|
-
function checkStat(
|
|
3380
|
-
return
|
|
3379
|
+
function checkStat(stat3, options) {
|
|
3380
|
+
return stat3.isFile() && checkMode(stat3, options);
|
|
3381
3381
|
}
|
|
3382
|
-
function checkMode(
|
|
3383
|
-
var mod =
|
|
3384
|
-
var uid =
|
|
3385
|
-
var gid =
|
|
3382
|
+
function checkMode(stat3, options) {
|
|
3383
|
+
var mod = stat3.mode;
|
|
3384
|
+
var uid = stat3.uid;
|
|
3385
|
+
var gid = stat3.gid;
|
|
3386
3386
|
var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
|
|
3387
3387
|
var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
|
|
3388
3388
|
var u2 = parseInt("100", 8);
|
|
@@ -3801,7 +3801,7 @@ var require_cross_spawn = __commonJS({
|
|
|
3801
3801
|
var cp = require("child_process");
|
|
3802
3802
|
var parse = require_parse();
|
|
3803
3803
|
var enoent = require_enoent();
|
|
3804
|
-
function
|
|
3804
|
+
function spawn11(command, args, options) {
|
|
3805
3805
|
const parsed = parse(command, args, options);
|
|
3806
3806
|
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
3807
3807
|
enoent.hookChildProcess(spawned, parsed);
|
|
@@ -3813,8 +3813,8 @@ var require_cross_spawn = __commonJS({
|
|
|
3813
3813
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
3814
3814
|
return result;
|
|
3815
3815
|
}
|
|
3816
|
-
module2.exports =
|
|
3817
|
-
module2.exports.spawn =
|
|
3816
|
+
module2.exports = spawn11;
|
|
3817
|
+
module2.exports.spawn = spawn11;
|
|
3818
3818
|
module2.exports.sync = spawnSync2;
|
|
3819
3819
|
module2.exports._parse = parse;
|
|
3820
3820
|
module2.exports._enoent = enoent;
|
|
@@ -11566,20 +11566,28 @@ async function postRpcAndExit(method, params, opts = {}) {
|
|
|
11566
11566
|
}
|
|
11567
11567
|
|
|
11568
11568
|
// src/commands/cp.ts
|
|
11569
|
+
function collectExclude(val, acc) {
|
|
11570
|
+
acc.push(val);
|
|
11571
|
+
return acc;
|
|
11572
|
+
}
|
|
11573
|
+
function buildCpParams(boxPath, hostPath, opts) {
|
|
11574
|
+
const params = { boxPath, hostPath };
|
|
11575
|
+
if (opts.recursive === false) params.recursive = false;
|
|
11576
|
+
if (opts.exclude.length > 0) params.exclude = opts.exclude;
|
|
11577
|
+
if (opts.defaultExcludes === false) params.defaultExcludes = false;
|
|
11578
|
+
if (opts.yes) params.yes = true;
|
|
11579
|
+
return params;
|
|
11580
|
+
}
|
|
11569
11581
|
var cpCommand = new Command("cp").description("Copy a file/dir between this box and the host (gated by user prompt on the host wrapper)").addCommand(
|
|
11570
|
-
new Command("toHost").description("Copy box:<boxPath> -> host:<hostPath>").argument("<boxPath>", "source path inside the container").argument("<hostPath>", "destination path on the host").option("--no-recursive", "reserved; current implementation is always recursive (docker cp -a)").action(async (boxPath, hostPath, opts) => {
|
|
11571
|
-
const
|
|
11572
|
-
if (opts.recursive === false) params.recursive = false;
|
|
11573
|
-
const code = await postRpcAndExit("cp.toHost", params, {
|
|
11582
|
+
new Command("toHost").description("Copy box:<boxPath> -> host:<hostPath>").argument("<boxPath>", "source path inside the container").argument("<hostPath>", "destination path on the host").option("--no-recursive", "reserved; current implementation is always recursive (docker cp -a)").option("--exclude <pattern>", "exclude paths matching <pattern> (repeatable)", collectExclude, []).option("--no-default-excludes", "keep heavy dirs the host drops by default (.git, node_modules, ...)").option("-y, --yes", "copy even if the source is over the host size limit").action(async (boxPath, hostPath, opts) => {
|
|
11583
|
+
const code = await postRpcAndExit("cp.toHost", buildCpParams(boxPath, hostPath, opts), {
|
|
11574
11584
|
errorPrefix: "agentbox-ctl cp"
|
|
11575
11585
|
});
|
|
11576
11586
|
process.exit(code);
|
|
11577
11587
|
})
|
|
11578
11588
|
).addCommand(
|
|
11579
|
-
new Command("fromHost").description("Copy host:<hostPath> -> box:<boxPath>").argument("<hostPath>", "source path on the host").argument("<boxPath>", "destination path inside the container").option("--no-recursive", "reserved; current implementation is always recursive (docker cp -a)").action(async (hostPath, boxPath, opts) => {
|
|
11580
|
-
const
|
|
11581
|
-
if (opts.recursive === false) params.recursive = false;
|
|
11582
|
-
const code = await postRpcAndExit("cp.fromHost", params, {
|
|
11589
|
+
new Command("fromHost").description("Copy host:<hostPath> -> box:<boxPath>").argument("<hostPath>", "source path on the host").argument("<boxPath>", "destination path inside the container").option("--no-recursive", "reserved; current implementation is always recursive (docker cp -a)").option("--exclude <pattern>", "exclude paths matching <pattern> (repeatable)", collectExclude, []).option("--no-default-excludes", "keep heavy dirs the host drops by default (.git, node_modules, ...)").option("-y, --yes", "copy even if the source is over the host size limit").action(async (hostPath, boxPath, opts) => {
|
|
11590
|
+
const code = await postRpcAndExit("cp.fromHost", buildCpParams(boxPath, hostPath, opts), {
|
|
11583
11591
|
errorPrefix: "agentbox-ctl cp"
|
|
11584
11592
|
});
|
|
11585
11593
|
process.exit(code);
|
|
@@ -12239,11 +12247,11 @@ var replacements = Object.entries(specialMainSymbols);
|
|
|
12239
12247
|
// ../../node_modules/.pnpm/yoctocolors@2.1.2/node_modules/yoctocolors/base.js
|
|
12240
12248
|
var import_node_tty = __toESM(require("tty"), 1);
|
|
12241
12249
|
var hasColors = import_node_tty.default?.WriteStream?.prototype?.hasColors?.() ?? false;
|
|
12242
|
-
var format = (
|
|
12250
|
+
var format = (open2, close) => {
|
|
12243
12251
|
if (!hasColors) {
|
|
12244
12252
|
return (input) => input;
|
|
12245
12253
|
}
|
|
12246
|
-
const openCode = `\x1B[${
|
|
12254
|
+
const openCode = `\x1B[${open2}m`;
|
|
12247
12255
|
const closeCode = `\x1B[${close}m`;
|
|
12248
12256
|
return (input) => {
|
|
12249
12257
|
const string = input + "";
|
|
@@ -18468,12 +18476,121 @@ var import_path2 = require("path");
|
|
|
18468
18476
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
18469
18477
|
var import_path3 = require("path");
|
|
18470
18478
|
var import_yaml3 = __toESM(require_dist(), 1);
|
|
18479
|
+
var BUILT_IN_DEFAULTS = {
|
|
18480
|
+
box: {
|
|
18481
|
+
provider: "docker",
|
|
18482
|
+
hostSnapshot: void 0,
|
|
18483
|
+
defaultCheckpoint: "",
|
|
18484
|
+
defaultCheckpointDocker: "",
|
|
18485
|
+
defaultCheckpointDaytona: "",
|
|
18486
|
+
defaultCheckpointHetzner: "",
|
|
18487
|
+
defaultCheckpointVercel: "",
|
|
18488
|
+
defaultCheckpointE2b: "",
|
|
18489
|
+
size: "",
|
|
18490
|
+
sizeDocker: "",
|
|
18491
|
+
sizeDaytona: "",
|
|
18492
|
+
sizeHetzner: "",
|
|
18493
|
+
sizeVercel: "",
|
|
18494
|
+
sizeE2b: "",
|
|
18495
|
+
withPlaywright: false,
|
|
18496
|
+
withEnv: false,
|
|
18497
|
+
resyncOnStart: true,
|
|
18498
|
+
vnc: true,
|
|
18499
|
+
autoApproveHostActions: false,
|
|
18500
|
+
isolateClaudeConfig: false,
|
|
18501
|
+
isolateCodexConfig: false,
|
|
18502
|
+
isolateOpencodeConfig: false,
|
|
18503
|
+
image: "agentbox/box:dev",
|
|
18504
|
+
imageDocker: "",
|
|
18505
|
+
imageDaytona: "",
|
|
18506
|
+
imageHetzner: "",
|
|
18507
|
+
imageVercel: "",
|
|
18508
|
+
imageE2b: "",
|
|
18509
|
+
// Mirrors BOX_IMAGE_REGISTRY in @agentbox/sandbox-docker. Empty disables the
|
|
18510
|
+
// registry pull (always build the docker base image locally).
|
|
18511
|
+
imageRegistry: "ghcr.io/madarco/agentbox/box",
|
|
18512
|
+
dockerCacheShared: false,
|
|
18513
|
+
memory: 0,
|
|
18514
|
+
cpus: 0,
|
|
18515
|
+
pidsLimit: 0,
|
|
18516
|
+
disk: "",
|
|
18517
|
+
bundleDepth: void 0,
|
|
18518
|
+
vercelVcpus: 2,
|
|
18519
|
+
vercelTimeoutMs: 27e5,
|
|
18520
|
+
vercelNetworkPolicy: "",
|
|
18521
|
+
cpMaxBytes: 100 * 1024 * 1024
|
|
18522
|
+
},
|
|
18523
|
+
checkpoint: {
|
|
18524
|
+
maxLayers: 3
|
|
18525
|
+
},
|
|
18526
|
+
claude: {
|
|
18527
|
+
sessionName: "claude",
|
|
18528
|
+
dangerouslySkipPermissions: true
|
|
18529
|
+
},
|
|
18530
|
+
codex: {
|
|
18531
|
+
sessionName: "codex",
|
|
18532
|
+
dangerouslySkipPermissions: true
|
|
18533
|
+
},
|
|
18534
|
+
opencode: {
|
|
18535
|
+
sessionName: "opencode"
|
|
18536
|
+
},
|
|
18537
|
+
attach: {
|
|
18538
|
+
openIn: "split",
|
|
18539
|
+
cmuxStatus: true
|
|
18540
|
+
},
|
|
18541
|
+
code: {
|
|
18542
|
+
ide: "auto",
|
|
18543
|
+
wait: true,
|
|
18544
|
+
timeoutMs: 12e4,
|
|
18545
|
+
autoTerminals: true
|
|
18546
|
+
},
|
|
18547
|
+
shell: {
|
|
18548
|
+
user: "vscode",
|
|
18549
|
+
login: true,
|
|
18550
|
+
tmux: true
|
|
18551
|
+
},
|
|
18552
|
+
engine: {
|
|
18553
|
+
kind: "auto"
|
|
18554
|
+
},
|
|
18555
|
+
browser: {
|
|
18556
|
+
default: "agent-browser"
|
|
18557
|
+
},
|
|
18558
|
+
relay: {
|
|
18559
|
+
port: 8787
|
|
18560
|
+
},
|
|
18561
|
+
vnc: {
|
|
18562
|
+
containerPort: 6080
|
|
18563
|
+
},
|
|
18564
|
+
portless: {
|
|
18565
|
+
enabled: void 0,
|
|
18566
|
+
stateDir: ""
|
|
18567
|
+
},
|
|
18568
|
+
autopause: {
|
|
18569
|
+
enabled: true,
|
|
18570
|
+
maxRunningBoxes: 5,
|
|
18571
|
+
idleMinutes: 5
|
|
18572
|
+
},
|
|
18573
|
+
queue: {
|
|
18574
|
+
enabled: true,
|
|
18575
|
+
maxConcurrent: 5,
|
|
18576
|
+
maxWorking: 0,
|
|
18577
|
+
idleGraceSeconds: 15,
|
|
18578
|
+
openIn: "none"
|
|
18579
|
+
},
|
|
18580
|
+
cloud: {
|
|
18581
|
+
useCurrentBranch: false
|
|
18582
|
+
},
|
|
18583
|
+
maintenance: {
|
|
18584
|
+
pruneProjectConfigs: true,
|
|
18585
|
+
pruneProjectConfigsEvery: 50
|
|
18586
|
+
}
|
|
18587
|
+
};
|
|
18471
18588
|
var KEY_REGISTRY = [
|
|
18472
18589
|
{
|
|
18473
18590
|
key: "box.provider",
|
|
18474
18591
|
type: "enum",
|
|
18475
|
-
enumValues: ["docker", "daytona", "hetzner", "vercel"],
|
|
18476
|
-
description: "Sandbox backend new boxes are created on: local Docker containers, Daytona Cloud sandboxes, Hetzner Cloud VPSes, or
|
|
18592
|
+
enumValues: ["docker", "daytona", "hetzner", "vercel", "e2b"],
|
|
18593
|
+
description: "Sandbox backend new boxes are created on: local Docker containers, Daytona Cloud sandboxes, Hetzner Cloud VPSes, Vercel Sandboxes, or E2B microVMs."
|
|
18477
18594
|
},
|
|
18478
18595
|
{
|
|
18479
18596
|
key: "box.hostSnapshot",
|
|
@@ -18509,6 +18626,12 @@ var KEY_REGISTRY = [
|
|
|
18509
18626
|
description: "Per-provider override of `box.defaultCheckpoint` for vercel. Wins over the global when set; set via `agentbox checkpoint set-default --provider vercel`.",
|
|
18510
18627
|
advanced: true
|
|
18511
18628
|
},
|
|
18629
|
+
{
|
|
18630
|
+
key: "box.defaultCheckpointE2b",
|
|
18631
|
+
type: "string",
|
|
18632
|
+
description: "Per-provider override of `box.defaultCheckpoint` for e2b. Wins over the global when set; set via `agentbox checkpoint set-default --provider e2b`.",
|
|
18633
|
+
advanced: true
|
|
18634
|
+
},
|
|
18512
18635
|
{
|
|
18513
18636
|
key: "box.size",
|
|
18514
18637
|
type: "string",
|
|
@@ -18538,6 +18661,12 @@ var KEY_REGISTRY = [
|
|
|
18538
18661
|
description: "Per-provider override of `box.size` for vercel. Reserved \u2014 vercel sizing is controlled via `box.vercelVcpus`.",
|
|
18539
18662
|
advanced: true
|
|
18540
18663
|
},
|
|
18664
|
+
{
|
|
18665
|
+
key: "box.sizeE2b",
|
|
18666
|
+
type: "string",
|
|
18667
|
+
description: "Per-provider override of `box.size` for e2b. Reserved \u2014 e2b sizing is template-level (set at `agentbox prepare --provider e2b` time via --vcpus / --memory).",
|
|
18668
|
+
advanced: true
|
|
18669
|
+
},
|
|
18541
18670
|
{
|
|
18542
18671
|
key: "checkpoint.maxLayers",
|
|
18543
18672
|
type: "int",
|
|
@@ -18564,6 +18693,11 @@ var KEY_REGISTRY = [
|
|
|
18564
18693
|
type: "bool",
|
|
18565
18694
|
description: "Run the per-box Xvnc + noVNC stack."
|
|
18566
18695
|
},
|
|
18696
|
+
{
|
|
18697
|
+
key: "box.autoApproveHostActions",
|
|
18698
|
+
type: "bool",
|
|
18699
|
+
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)."
|
|
18700
|
+
},
|
|
18567
18701
|
{
|
|
18568
18702
|
key: "box.isolateClaudeConfig",
|
|
18569
18703
|
type: "bool",
|
|
@@ -18609,6 +18743,12 @@ var KEY_REGISTRY = [
|
|
|
18609
18743
|
description: "Per-provider override of `box.image` for vercel (snapshot id, e.g. `snap_\u2026`). Written by `agentbox prepare --provider vercel`.",
|
|
18610
18744
|
advanced: true
|
|
18611
18745
|
},
|
|
18746
|
+
{
|
|
18747
|
+
key: "box.imageE2b",
|
|
18748
|
+
type: "string",
|
|
18749
|
+
description: "Per-provider override of `box.image` for e2b (template id or `name:tag`, e.g. `agentbox-base:latest`). Written by `agentbox prepare --provider e2b`.",
|
|
18750
|
+
advanced: true
|
|
18751
|
+
},
|
|
18612
18752
|
{
|
|
18613
18753
|
key: "box.imageRegistry",
|
|
18614
18754
|
type: "string",
|
|
@@ -18656,6 +18796,12 @@ var KEY_REGISTRY = [
|
|
|
18656
18796
|
type: "int",
|
|
18657
18797
|
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."
|
|
18658
18798
|
},
|
|
18799
|
+
{
|
|
18800
|
+
key: "box.cpMaxBytes",
|
|
18801
|
+
type: "int",
|
|
18802
|
+
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).",
|
|
18803
|
+
advanced: true
|
|
18804
|
+
},
|
|
18659
18805
|
{
|
|
18660
18806
|
key: "box.vercelNetworkPolicy",
|
|
18661
18807
|
type: "string",
|
|
@@ -18803,6 +18949,12 @@ var KEY_REGISTRY = [
|
|
|
18803
18949
|
type: "int",
|
|
18804
18950
|
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."
|
|
18805
18951
|
},
|
|
18952
|
+
{
|
|
18953
|
+
key: "queue.openIn",
|
|
18954
|
+
type: "enum",
|
|
18955
|
+
enumValues: ["none", "split", "window", "tab"],
|
|
18956
|
+
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."
|
|
18957
|
+
},
|
|
18806
18958
|
{
|
|
18807
18959
|
key: "cloud.useCurrentBranch",
|
|
18808
18960
|
type: "bool",
|
|
@@ -18990,6 +19142,21 @@ var EventBuffer = class {
|
|
|
18990
19142
|
};
|
|
18991
19143
|
var PendingPrompts = class {
|
|
18992
19144
|
entries = /* @__PURE__ */ new Map();
|
|
19145
|
+
autoApprove = null;
|
|
19146
|
+
/** Install the per-box auto-approve policy (relay server, once at startup). */
|
|
19147
|
+
setAutoApprovePolicy(policy) {
|
|
19148
|
+
this.autoApprove = policy;
|
|
19149
|
+
}
|
|
19150
|
+
/**
|
|
19151
|
+
* True when this box opted into `box.autoApproveHostActions`. Records the
|
|
19152
|
+
* bypass to the audit sink as a side effect so the caller short-circuits
|
|
19153
|
+
* with a trail. Returns false when no policy is installed.
|
|
19154
|
+
*/
|
|
19155
|
+
consumeAutoApprove(boxId, params) {
|
|
19156
|
+
if (!this.autoApprove || !this.autoApprove.shouldAutoApprove(boxId)) return false;
|
|
19157
|
+
this.autoApprove.audit(boxId, params);
|
|
19158
|
+
return true;
|
|
19159
|
+
}
|
|
18993
19160
|
add(boxId, ev) {
|
|
18994
19161
|
return new Promise((resolve2) => {
|
|
18995
19162
|
this.entries.set(ev.id, {
|
|
@@ -19076,6 +19243,9 @@ async function askPrompt(prompts, subscribers, boxId, params, opts) {
|
|
|
19076
19243
|
if (process.env.AGENTBOX_PROMPT === "off") {
|
|
19077
19244
|
return { answer: "y" };
|
|
19078
19245
|
}
|
|
19246
|
+
if (prompts.consumeAutoApprove(boxId, params)) {
|
|
19247
|
+
return { answer: "y" };
|
|
19248
|
+
}
|
|
19079
19249
|
const ev = { id: (0, import_crypto2.randomUUID)(), ...params };
|
|
19080
19250
|
const promise = prompts.add(boxId, ev);
|
|
19081
19251
|
subscribers.broadcast(boxId, "prompt-ask", ev);
|
|
@@ -19544,6 +19714,10 @@ async function resolveCloudBackend(name) {
|
|
|
19544
19714
|
const pkg = "@agentbox/sandbox-vercel";
|
|
19545
19715
|
return loadCloudBackend(pkg, async () => (await import(pkg)).vercelBackend);
|
|
19546
19716
|
}
|
|
19717
|
+
if (name === "e2b") {
|
|
19718
|
+
const pkg = "@agentbox/sandbox-e2b";
|
|
19719
|
+
return loadCloudBackend(pkg, async () => (await import(pkg)).e2bBackend);
|
|
19720
|
+
}
|
|
19547
19721
|
throw new Error(`no host executor for cloud backend '${name}'`);
|
|
19548
19722
|
}
|
|
19549
19723
|
async function loadCloudBackend(pkg, load2) {
|
|
@@ -20218,6 +20392,21 @@ function createRelayServer(opts) {
|
|
|
20218
20392
|
const prompts = new PendingPrompts();
|
|
20219
20393
|
const subscribers = new PromptSubscribers();
|
|
20220
20394
|
const notices = new BoxNotices(subscribers);
|
|
20395
|
+
prompts.setAutoApprovePolicy({
|
|
20396
|
+
shouldAutoApprove: (boxId) => registry.get(boxId)?.autoApproveHostActions === true,
|
|
20397
|
+
audit: (boxId, params) => {
|
|
20398
|
+
events.append({
|
|
20399
|
+
boxId,
|
|
20400
|
+
type: "host-action-auto-approved",
|
|
20401
|
+
payload: {
|
|
20402
|
+
command: params.context?.command,
|
|
20403
|
+
argv: params.context?.argv,
|
|
20404
|
+
message: params.message
|
|
20405
|
+
}
|
|
20406
|
+
});
|
|
20407
|
+
log(`auto-approved host action for ${boxId}: ${params.context?.command ?? params.message}`);
|
|
20408
|
+
}
|
|
20409
|
+
});
|
|
20221
20410
|
const hostInitiatedTokens = new HostInitiatedTokens();
|
|
20222
20411
|
let queuePoke = null;
|
|
20223
20412
|
const host = opts.host ?? "0.0.0.0";
|
|
@@ -20405,11 +20594,22 @@ function createRelayServer(opts) {
|
|
|
20405
20594
|
send(res, 400, { error: "cp.* requires {boxPath, hostPath} strings" });
|
|
20406
20595
|
return;
|
|
20407
20596
|
}
|
|
20597
|
+
if (params.exclude !== void 0 && (!Array.isArray(params.exclude) || params.exclude.some((p) => typeof p !== "string"))) {
|
|
20598
|
+
send(res, 400, { error: "cp.* exclude must be an array of strings" });
|
|
20599
|
+
return;
|
|
20600
|
+
}
|
|
20408
20601
|
const direction = body.method === "cp.toHost" ? "box -> host" : "host -> box";
|
|
20602
|
+
const pathDetail = body.method === "cp.toHost" ? `${params.boxPath} -> ${params.hostPath}` : `${params.hostPath} -> ${params.boxPath}`;
|
|
20603
|
+
const detailParts = [pathDetail];
|
|
20604
|
+
if (params.exclude && params.exclude.length > 0) {
|
|
20605
|
+
detailParts.push(`exclude: ${params.exclude.join(", ")}`);
|
|
20606
|
+
}
|
|
20607
|
+
if (params.defaultExcludes === false) detailParts.push("(default excludes off)");
|
|
20608
|
+
if (params.yes) detailParts.push("(over size limit \u2014 confirmed)");
|
|
20409
20609
|
const verdict = await askPrompt(prompts, subscribers, reg.boxId, {
|
|
20410
20610
|
kind: "confirm",
|
|
20411
20611
|
message: `Allow cp (${direction}) on ${reg.name}?`,
|
|
20412
|
-
detail:
|
|
20612
|
+
detail: detailParts.join("\n"),
|
|
20413
20613
|
defaultAnswer: "n",
|
|
20414
20614
|
context: {
|
|
20415
20615
|
command: body.method,
|
|
@@ -20575,7 +20775,8 @@ function createRelayServer(opts) {
|
|
|
20575
20775
|
worktrees,
|
|
20576
20776
|
previewUrl: typeof body.previewUrl === "string" && body.previewUrl.length > 0 ? body.previewUrl : void 0,
|
|
20577
20777
|
previewToken: typeof body.previewToken === "string" && body.previewToken.length > 0 ? body.previewToken : void 0,
|
|
20578
|
-
bridgeToken: typeof body.bridgeToken === "string" && body.bridgeToken.length > 0 ? body.bridgeToken : void 0
|
|
20778
|
+
bridgeToken: typeof body.bridgeToken === "string" && body.bridgeToken.length > 0 ? body.bridgeToken : void 0,
|
|
20779
|
+
autoApproveHostActions: body.autoApproveHostActions === true
|
|
20579
20780
|
};
|
|
20580
20781
|
registry.register(reg);
|
|
20581
20782
|
log(
|
|
@@ -20683,6 +20884,15 @@ function createRelayServer(opts) {
|
|
|
20683
20884
|
send(res, 200, { boxes: redacted });
|
|
20684
20885
|
return;
|
|
20685
20886
|
}
|
|
20887
|
+
if (route === "GET /admin/prompts") {
|
|
20888
|
+
const boxId = url.searchParams.get("boxId") ?? "";
|
|
20889
|
+
if (boxId.length === 0) {
|
|
20890
|
+
send(res, 400, { error: "missing boxId query param" });
|
|
20891
|
+
return;
|
|
20892
|
+
}
|
|
20893
|
+
send(res, 200, { prompts: prompts.forBox(boxId) });
|
|
20894
|
+
return;
|
|
20895
|
+
}
|
|
20686
20896
|
if (route === "GET /admin/prompts/stream") {
|
|
20687
20897
|
const boxId = url.searchParams.get("boxId") ?? "";
|
|
20688
20898
|
if (boxId.length === 0) {
|
|
@@ -21000,7 +21210,11 @@ async function handleCpRpc(reg, method, params) {
|
|
|
21000
21210
|
};
|
|
21001
21211
|
}
|
|
21002
21212
|
const boxRef = `${reg.name}:${params.boxPath}`;
|
|
21003
|
-
const
|
|
21213
|
+
const flags = [];
|
|
21214
|
+
for (const pat of params.exclude ?? []) flags.push("--exclude", pat);
|
|
21215
|
+
if (params.defaultExcludes === false) flags.push("--no-default-excludes");
|
|
21216
|
+
if (params.yes) flags.push("--yes");
|
|
21217
|
+
const argv = method === "cp.toHost" ? [process.execPath, entry, "cp", boxRef, params.hostPath, ...flags] : [process.execPath, entry, "cp", params.hostPath, boxRef, ...flags];
|
|
21004
21218
|
return runHostCommand(argv, CP_RPC_TIMEOUT_MS);
|
|
21005
21219
|
}
|
|
21006
21220
|
async function handleDownloadRpc(reg, kind) {
|
|
@@ -21097,6 +21311,8 @@ async function startRelayServer(opts) {
|
|
|
21097
21311
|
return handle;
|
|
21098
21312
|
}
|
|
21099
21313
|
var QUEUE_DIR = (0, import_path6.join)(STATE_DIR, "queue");
|
|
21314
|
+
var TERMINAL_RETENTION_MS = 60 * 60 * 1e3;
|
|
21315
|
+
var SWEEP_INTERVAL_MS = 60 * 1e3;
|
|
21100
21316
|
var QUEUE_LOGS_DIR = (0, import_path6.join)(STATE_DIR, "logs");
|
|
21101
21317
|
|
|
21102
21318
|
// src/config.ts
|
|
@@ -21615,8 +21831,68 @@ function defaultCapturePane(sessionName) {
|
|
|
21615
21831
|
});
|
|
21616
21832
|
}
|
|
21617
21833
|
|
|
21618
|
-
// src/
|
|
21834
|
+
// src/claude-scraper.ts
|
|
21619
21835
|
var import_node_child_process8 = require("child_process");
|
|
21836
|
+
var DEFAULT_INTERVAL_MS2 = 1500;
|
|
21837
|
+
var DEFAULT_SESSION2 = "claude";
|
|
21838
|
+
var BOTTOM_LINES = 25;
|
|
21839
|
+
var WORKING_GUARD = /\besc to interrupt\b|ctrl-?c to (stop|interrupt)/i;
|
|
21840
|
+
var WAITING_PATTERNS = [
|
|
21841
|
+
/❯\s*\d+\.\s/,
|
|
21842
|
+
// the selector arrow on a numbered option — the Claude select menu
|
|
21843
|
+
/Do you want to proceed\?/i,
|
|
21844
|
+
/Would you like to proceed\?/i,
|
|
21845
|
+
/\b\d+\.\s+Yes\b/,
|
|
21846
|
+
// a "N. Yes" option line
|
|
21847
|
+
/\b(wants to (use|run|access)|Allow .* to (use|run|access))/i
|
|
21848
|
+
// MCP / tool trust dialog
|
|
21849
|
+
];
|
|
21850
|
+
function startClaudeScraper(opts) {
|
|
21851
|
+
const sessionName = opts.sessionName ?? DEFAULT_SESSION2;
|
|
21852
|
+
const intervalMs = opts.intervalMs ?? DEFAULT_INTERVAL_MS2;
|
|
21853
|
+
const capture = opts.capturePane ?? defaultCapturePane2;
|
|
21854
|
+
let stopped = false;
|
|
21855
|
+
const tick = async () => {
|
|
21856
|
+
if (stopped) return;
|
|
21857
|
+
try {
|
|
21858
|
+
const pane = await capture(sessionName);
|
|
21859
|
+
if (pane === null) return;
|
|
21860
|
+
if (matchWaiting(pane)) opts.reporter.markScreenWaiting();
|
|
21861
|
+
} catch {
|
|
21862
|
+
}
|
|
21863
|
+
};
|
|
21864
|
+
const timer = setInterval(() => void tick(), intervalMs);
|
|
21865
|
+
timer.unref();
|
|
21866
|
+
void tick();
|
|
21867
|
+
return {
|
|
21868
|
+
stop() {
|
|
21869
|
+
stopped = true;
|
|
21870
|
+
clearInterval(timer);
|
|
21871
|
+
}
|
|
21872
|
+
};
|
|
21873
|
+
}
|
|
21874
|
+
function matchWaiting(pane) {
|
|
21875
|
+
const region = pane.split("\n").slice(-BOTTOM_LINES).join("\n");
|
|
21876
|
+
if (WORKING_GUARD.test(region)) return false;
|
|
21877
|
+
return WAITING_PATTERNS.some((re) => re.test(region));
|
|
21878
|
+
}
|
|
21879
|
+
function defaultCapturePane2(sessionName) {
|
|
21880
|
+
return new Promise((resolve2) => {
|
|
21881
|
+
const child = (0, import_node_child_process8.spawn)("tmux", ["capture-pane", "-p", "-t", sessionName], {
|
|
21882
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
21883
|
+
});
|
|
21884
|
+
let stdout = "";
|
|
21885
|
+
child.stdout.on("data", (b) => stdout += b.toString("utf8"));
|
|
21886
|
+
child.on("error", () => resolve2(null));
|
|
21887
|
+
child.on("close", (code) => {
|
|
21888
|
+
if (code === 0) resolve2(stdout);
|
|
21889
|
+
else resolve2(null);
|
|
21890
|
+
});
|
|
21891
|
+
});
|
|
21892
|
+
}
|
|
21893
|
+
|
|
21894
|
+
// src/supervisor.ts
|
|
21895
|
+
var import_node_child_process9 = require("child_process");
|
|
21620
21896
|
var import_node_events15 = require("events");
|
|
21621
21897
|
var import_node_fs7 = require("fs");
|
|
21622
21898
|
var import_promises18 = require("fs/promises");
|
|
@@ -21882,7 +22158,7 @@ var cachedLoginPath;
|
|
|
21882
22158
|
function loginShellPath() {
|
|
21883
22159
|
if (cachedLoginPath !== void 0) return cachedLoginPath;
|
|
21884
22160
|
try {
|
|
21885
|
-
const out = (0,
|
|
22161
|
+
const out = (0, import_node_child_process9.execFileSync)("bash", ["-lc", 'printf %s "$PATH"'], {
|
|
21886
22162
|
encoding: "utf8",
|
|
21887
22163
|
timeout: 5e3
|
|
21888
22164
|
}).trim();
|
|
@@ -21897,7 +22173,7 @@ var ServiceRunner = class extends import_node_events15.EventEmitter {
|
|
|
21897
22173
|
super();
|
|
21898
22174
|
this.spec = spec;
|
|
21899
22175
|
this.opts = opts;
|
|
21900
|
-
this.spawnFn = opts.spawn ??
|
|
22176
|
+
this.spawnFn = opts.spawn ?? import_node_child_process9.spawn;
|
|
21901
22177
|
this.setTimer = opts.setTimer ?? ((fn, ms) => setTimeout(fn, ms));
|
|
21902
22178
|
this.clearTimer = opts.clearTimer ?? ((h2) => {
|
|
21903
22179
|
clearTimeout(h2);
|
|
@@ -22128,7 +22404,7 @@ var TaskRunner = class extends import_node_events15.EventEmitter {
|
|
|
22128
22404
|
super();
|
|
22129
22405
|
this.spec = spec;
|
|
22130
22406
|
this.opts = opts;
|
|
22131
|
-
this.spawnFn = opts.spawn ??
|
|
22407
|
+
this.spawnFn = opts.spawn ?? import_node_child_process9.spawn;
|
|
22132
22408
|
}
|
|
22133
22409
|
spec;
|
|
22134
22410
|
opts;
|
|
@@ -22301,6 +22577,20 @@ var Supervisor = class extends import_node_events15.EventEmitter {
|
|
|
22301
22577
|
}
|
|
22302
22578
|
return out;
|
|
22303
22579
|
}
|
|
22580
|
+
/**
|
|
22581
|
+
* Set of service names that declare a `ready_when` probe of any kind (port or
|
|
22582
|
+
* log_match). A probed service is only "up" once it reaches `ready`; an
|
|
22583
|
+
* unprobed one is up at `running`. The status reporter surfaces this so the
|
|
22584
|
+
* host can tell a warming-up `running` service from a settled one.
|
|
22585
|
+
*/
|
|
22586
|
+
probedServices() {
|
|
22587
|
+
const out = /* @__PURE__ */ new Set();
|
|
22588
|
+
for (const u2 of this.units.values()) {
|
|
22589
|
+
if (u2.kind !== "service") continue;
|
|
22590
|
+
if (u2.spec.readyWhen) out.add(u2.name);
|
|
22591
|
+
}
|
|
22592
|
+
return out;
|
|
22593
|
+
}
|
|
22304
22594
|
/**
|
|
22305
22595
|
* Map of service name -> `expose:` mapping, for the (at most one) service
|
|
22306
22596
|
* that declares it. The status reporter surfaces this so the host knows the
|
|
@@ -22677,10 +22967,10 @@ var import_promises19 = require("fs/promises");
|
|
|
22677
22967
|
var import_node_path7 = require("path");
|
|
22678
22968
|
|
|
22679
22969
|
// src/status-reporter.ts
|
|
22680
|
-
var
|
|
22970
|
+
var import_node_child_process11 = require("child_process");
|
|
22681
22971
|
|
|
22682
22972
|
// src/tmux.ts
|
|
22683
|
-
var
|
|
22973
|
+
var import_node_child_process10 = require("child_process");
|
|
22684
22974
|
var import_node_os4 = require("os");
|
|
22685
22975
|
var MAX_TITLE_LEN = 120;
|
|
22686
22976
|
function sanitizePaneTitle(raw, ctx) {
|
|
@@ -22694,7 +22984,7 @@ function sanitizePaneTitle(raw, ctx) {
|
|
|
22694
22984
|
}
|
|
22695
22985
|
function runTool(cmd, args) {
|
|
22696
22986
|
return new Promise((resolve2) => {
|
|
22697
|
-
const child = (0,
|
|
22987
|
+
const child = (0, import_node_child_process10.spawn)(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
22698
22988
|
let stdout = "";
|
|
22699
22989
|
let stderr = "";
|
|
22700
22990
|
child.stdout.on("data", (b) => stdout += b.toString("utf8"));
|
|
@@ -22791,6 +23081,23 @@ var StatusReporter = class {
|
|
|
22791
23081
|
}
|
|
22792
23082
|
this.schedulePush();
|
|
22793
23083
|
}
|
|
23084
|
+
/**
|
|
23085
|
+
* Screen-scraper safety net: promote a *stuck* `working` to `waiting` when the
|
|
23086
|
+
* Claude tmux pane shows a prompt the hooks missed (MCP tool dialogs have no
|
|
23087
|
+
* hook; the `Notification:permission_prompt` hook can fire late or drop).
|
|
23088
|
+
* Deliberately promote-ONLY — it acts solely when the current state is
|
|
23089
|
+
* `working`, so it never clobbers the richer hook-driven `end-plan`/`question`
|
|
23090
|
+
* (sticky) or `idle`/`compacting`/`error`. The next real hook
|
|
23091
|
+
* (`UserPromptSubmit`/`PreToolUse`) overwrites `waiting`→`working` when the
|
|
23092
|
+
* agent resumes, so no demote path is needed. Returns true if it promoted.
|
|
23093
|
+
*/
|
|
23094
|
+
markScreenWaiting() {
|
|
23095
|
+
if (this.claudeState !== "working") return false;
|
|
23096
|
+
this.claudeState = "waiting";
|
|
23097
|
+
this.claudeUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
23098
|
+
this.schedulePush();
|
|
23099
|
+
return true;
|
|
23100
|
+
}
|
|
22794
23101
|
setCodexState(state) {
|
|
22795
23102
|
this.codexState = state;
|
|
22796
23103
|
this.codexUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -22827,11 +23134,13 @@ var StatusReporter = class {
|
|
|
22827
23134
|
}
|
|
22828
23135
|
async snapshot() {
|
|
22829
23136
|
const probePorts = this.supervisor.serviceProbePorts();
|
|
23137
|
+
const probed = this.supervisor.probedServices();
|
|
22830
23138
|
const exposes = this.supervisor.serviceExposes();
|
|
22831
23139
|
const services = this.supervisor.list().map((s) => ({
|
|
22832
23140
|
name: s.name,
|
|
22833
23141
|
state: s.state,
|
|
22834
23142
|
port: probePorts.get(s.name) ?? null,
|
|
23143
|
+
...probed.has(s.name) ? { probed: true } : {},
|
|
22835
23144
|
...exposes.has(s.name) ? { expose: exposes.get(s.name) } : {}
|
|
22836
23145
|
}));
|
|
22837
23146
|
const tasks = this.supervisor.listTasks().map((t) => ({ name: t.name, state: t.state }));
|
|
@@ -22887,7 +23196,7 @@ async function collectPorts(supervisor) {
|
|
|
22887
23196
|
}
|
|
22888
23197
|
function run(cmd, args) {
|
|
22889
23198
|
return new Promise((resolve2) => {
|
|
22890
|
-
const child = (0,
|
|
23199
|
+
const child = (0, import_node_child_process11.spawn)(cmd, args, { stdio: ["ignore", "pipe", "ignore"] });
|
|
22891
23200
|
let stdout = "";
|
|
22892
23201
|
child.stdout.on("data", (b) => stdout += b.toString("utf8"));
|
|
22893
23202
|
child.on("error", () => resolve2({ exitCode: 127, stdout }));
|
|
@@ -23224,6 +23533,14 @@ var daemonCommand = new Command("daemon").description("Run the agentbox-ctl supe
|
|
|
23224
23533
|
} catch (err) {
|
|
23225
23534
|
const msg = err instanceof Error ? err.message : String(err);
|
|
23226
23535
|
process.stderr.write(`agentbox-ctl: codex scraper failed to start: ${msg}
|
|
23536
|
+
`);
|
|
23537
|
+
}
|
|
23538
|
+
let claudeScraper = null;
|
|
23539
|
+
try {
|
|
23540
|
+
claudeScraper = startClaudeScraper({ reporter });
|
|
23541
|
+
} catch (err) {
|
|
23542
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
23543
|
+
process.stderr.write(`agentbox-ctl: claude scraper failed to start: ${msg}
|
|
23227
23544
|
`);
|
|
23228
23545
|
}
|
|
23229
23546
|
const server = await startServer({
|
|
@@ -23301,6 +23618,7 @@ var daemonCommand = new Command("daemon").description("Run the agentbox-ctl supe
|
|
|
23301
23618
|
process.stdout.write(`agentbox-ctl: ${signal} \u2014 shutting down
|
|
23302
23619
|
`);
|
|
23303
23620
|
if (codexScraper) codexScraper.stop();
|
|
23621
|
+
if (claudeScraper) claudeScraper.stop();
|
|
23304
23622
|
reporter.stop();
|
|
23305
23623
|
reporter.flush();
|
|
23306
23624
|
server.close();
|
|
@@ -23462,7 +23780,7 @@ var apiCommand = new Command("api").description(
|
|
|
23462
23780
|
var ghCommand = new Command("gh").description("GitHub CLI operations routed through the relay (host `gh` runs with host creds; box never sees a token)").addCommand(buildPrCommand("agentbox-ctl gh pr")).addCommand(buildRunCommand("agentbox-ctl gh run")).addCommand(apiCommand).addCommand(repoCommand);
|
|
23463
23781
|
|
|
23464
23782
|
// src/commands/git.ts
|
|
23465
|
-
var
|
|
23783
|
+
var import_node_child_process12 = require("child_process");
|
|
23466
23784
|
function hostInitiatedOption() {
|
|
23467
23785
|
return new Option(
|
|
23468
23786
|
"--host-initiated-token <token>",
|
|
@@ -23478,7 +23796,7 @@ function buildParams(opts, extra) {
|
|
|
23478
23796
|
}
|
|
23479
23797
|
function runLocalGit(args, cwd) {
|
|
23480
23798
|
return new Promise((resolve2) => {
|
|
23481
|
-
const child = (0,
|
|
23799
|
+
const child = (0, import_node_child_process12.spawn)("git", args, { cwd, stdio: "inherit" });
|
|
23482
23800
|
child.on("close", (code) => resolve2(code ?? 1));
|
|
23483
23801
|
child.on("error", (err) => {
|
|
23484
23802
|
process.stderr.write(`agentbox-ctl git: ${String(err.message ?? err)}
|
|
@@ -23489,7 +23807,7 @@ function runLocalGit(args, cwd) {
|
|
|
23489
23807
|
}
|
|
23490
23808
|
function hasGitIdentity(cwd) {
|
|
23491
23809
|
return new Promise((resolve2) => {
|
|
23492
|
-
const child = (0,
|
|
23810
|
+
const child = (0, import_node_child_process12.spawn)("git", ["config", "user.email"], {
|
|
23493
23811
|
cwd,
|
|
23494
23812
|
stdio: ["ignore", "pipe", "ignore"]
|
|
23495
23813
|
});
|
|
@@ -23591,7 +23909,7 @@ var notifyCommand = new Command("notify").description(
|
|
|
23591
23909
|
);
|
|
23592
23910
|
|
|
23593
23911
|
// src/commands/open.ts
|
|
23594
|
-
var
|
|
23912
|
+
var import_node_child_process13 = require("child_process");
|
|
23595
23913
|
var OPEN_TIMEOUT_MS = 3e4;
|
|
23596
23914
|
function isHttpUrl(value) {
|
|
23597
23915
|
try {
|
|
@@ -23603,7 +23921,7 @@ function isHttpUrl(value) {
|
|
|
23603
23921
|
}
|
|
23604
23922
|
function openInBoxBrowser(url) {
|
|
23605
23923
|
return new Promise((resolve2) => {
|
|
23606
|
-
const child = (0,
|
|
23924
|
+
const child = (0, import_node_child_process13.spawn)("agent-browser", ["open", "--headed", url], { stdio: "inherit" });
|
|
23607
23925
|
const timer = setTimeout(() => {
|
|
23608
23926
|
child.kill("SIGTERM");
|
|
23609
23927
|
process.stderr.write(
|