@mybase-dev/cli 1.0.11 → 1.0.12

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.
Files changed (2) hide show
  1. package/dist/mybase.js +55 -13
  2. package/package.json +1 -1
package/dist/mybase.js CHANGED
@@ -109,7 +109,7 @@ var package_default;
109
109
  var init_package = __esm(() => {
110
110
  package_default = {
111
111
  name: "@mybase-dev/cli",
112
- version: "1.0.11",
112
+ version: "1.0.12",
113
113
  description: "The mybase CLI: projects, keys, cron, queues, cache, rate limits, analytics, docs, and agent setup for a self-hosted mybase.",
114
114
  type: "module",
115
115
  repository: {
@@ -1714,6 +1714,42 @@ function publicSandboxIp(ip) {
1714
1714
  }
1715
1715
  var init_public_ip = () => {};
1716
1716
 
1717
+ // ../../packages/shared/src/sandbox.ts
1718
+ function sandboxConfig(raw) {
1719
+ const config = { resources: { ...SANDBOX_RESOURCES }, limits: { ...SANDBOX_LIMITS } };
1720
+ if (!raw)
1721
+ return config;
1722
+ const input = JSON.parse(raw);
1723
+ if (!input || typeof input !== "object" || Array.isArray(input))
1724
+ throw new Error("MYBASE_SANDBOX_CONFIG must be a JSON object");
1725
+ for (const group of Object.keys(input)) {
1726
+ if (group !== "resources" && group !== "limits")
1727
+ throw new Error(`unknown sandbox config group: ${group}`);
1728
+ const values = input[group];
1729
+ if (!values || typeof values !== "object" || Array.isArray(values))
1730
+ throw new Error(`sandbox ${group} must be an object`);
1731
+ const target = config[group];
1732
+ for (const [key, value] of Object.entries(values)) {
1733
+ if (!Object.hasOwn(target, key))
1734
+ throw new Error(`unknown sandbox ${group} setting: ${key}`);
1735
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0 || key !== "cpus" && !Number.isSafeInteger(value))
1736
+ throw new Error(`sandbox ${key} must be a positive ${key === "cpus" ? "number" : "safe integer"}`);
1737
+ target[key] = value;
1738
+ }
1739
+ }
1740
+ return config;
1741
+ }
1742
+ var SANDBOX_RESOURCES, SANDBOX_LIMITS;
1743
+ var init_sandbox = __esm(() => {
1744
+ SANDBOX_RESOURCES = { cpus: 1, memoryMb: 1024, workspaceMb: 128, pids: 256, tmpMb: 256, shmMb: 64 };
1745
+ SANDBOX_LIMITS = {
1746
+ fileBytes: 8 * 1024 * 1024,
1747
+ outputBytes: 64 * 1024,
1748
+ networkStreams: 32,
1749
+ networkIdleMs: 15000
1750
+ };
1751
+ });
1752
+
1717
1753
  // ../../docker/compose.yml
1718
1754
  var compose_default = `# Runs mybase: the control plane (API + dashboard), the shared Postgres server, Garage
1719
1755
  # (S3-compatible storage), Valkey (Redis-compatible cache), and SearXNG (web search). All images are multi-arch (arm64 + amd64).
@@ -1831,6 +1867,7 @@ services:
1831
1867
  LOG_LEVEL: \${LOG_LEVEL:-info}
1832
1868
  MYBASE_SANDBOX_WORKER_URL: \${MYBASE_SANDBOX_WORKER_URL:-}
1833
1869
  MYBASE_SANDBOX_WORKER_KEY: \${MYBASE_SANDBOX_WORKER_KEY:-}
1870
+ MYBASE_SANDBOX_CONFIG: \${MYBASE_SANDBOX_CONFIG:-}
1834
1871
  ports:
1835
1872
  - "\${MYBASE_BIND:-0.0.0.0}:\${MYBASE_PORT:-4000}:4000"
1836
1873
 
@@ -1918,6 +1955,7 @@ services:
1918
1955
  environment:
1919
1956
  MYBASE_SANDBOX_WORKER_KEY: \${MYBASE_SANDBOX_WORKER_KEY:-}
1920
1957
  MYBASE_SANDBOX_DENY_HOSTS: \${MYBASE_SANDBOX_DENY_HOSTS:-}
1958
+ MYBASE_SANDBOX_CONFIG: \${MYBASE_SANDBOX_CONFIG:-}
1921
1959
  MYBASE_SANDBOX_IMAGE: \${MYBASE_SANDBOX_IMAGE:-ghcr.io/landonharter/mybase-sandbox:latest}
1922
1960
  LOG_LEVEL: \${LOG_LEVEL:-info}
1923
1961
  volumes:
@@ -3424,7 +3462,7 @@ async function sandboxWorkerHealth(dir, run = hostRun) {
3424
3462
  return null;
3425
3463
  }
3426
3464
  }
3427
- async function probeRuntime(image, run) {
3465
+ async function probeRuntime(image, run, resources) {
3428
3466
  const name = `mybase-sandbox-probe-${crypto.randomUUID()}`;
3429
3467
  const code = "const timer=setTimeout(()=>process.exit(1),15000);const {chromium}=require('/opt/runtime/node_modules/playwright');chromium.launch({headless:true,chromiumSandbox:false,args:['--disable-dev-shm-usage']}).then(async b=>{await b.close();clearTimeout(timer)}).catch(()=>process.exit(1))";
3430
3468
  try {
@@ -3439,16 +3477,17 @@ async function probeRuntime(image, run) {
3439
3477
  "--read-only",
3440
3478
  "--cap-drop=ALL",
3441
3479
  "--security-opt=no-new-privileges:true",
3442
- "--cpus=1",
3443
- "--memory=1024m",
3444
- "--memory-swap=1024m",
3445
- "--pids-limit=256",
3446
- "--ulimit=nproc=256:256",
3480
+ `--cpus=${resources.cpus}`,
3481
+ `--memory=${resources.memoryMb}m`,
3482
+ `--memory-swap=${resources.memoryMb}m`,
3483
+ `--pids-limit=${resources.pids}`,
3484
+ `--ulimit=nproc=${resources.pids}:${resources.pids}`,
3447
3485
  "--log-driver=none",
3448
3486
  "--tmpfs",
3449
- "/tmp:rw,nosuid,nodev,size=256m,uid=1000,gid=1000,mode=0700",
3487
+ `/tmp:rw,nosuid,nodev,size=${resources.tmpMb}m,uid=1000,gid=1000,mode=0700`,
3450
3488
  "--tmpfs",
3451
- "/workspace:rw,nosuid,nodev,size=128m,uid=1000,gid=1000,mode=0700",
3489
+ `/workspace:rw,nosuid,nodev,size=${resources.workspaceMb}m,uid=1000,gid=1000,mode=0700`,
3490
+ `--shm-size=${resources.shmMb}m`,
3452
3491
  "--entrypoint",
3453
3492
  "node",
3454
3493
  image,
@@ -3471,6 +3510,7 @@ async function prepareSandboxHost(args, options = {}, overrides = {}) {
3471
3510
  throw new CliError(`no mybase server in ${dir}; run mybase server setup --sandboxes first`, 4);
3472
3511
  const text = await file.text();
3473
3512
  const values = parseEnv(text);
3513
+ const config = sandboxConfig(values.MYBASE_SANDBOX_CONFIG);
3474
3514
  const interactive = !jsonMode && process.stdin.isTTY === true && !args.includes("--yes");
3475
3515
  if (!options.confirmed && !args.includes("--yes")) {
3476
3516
  if (!interactive)
@@ -3517,7 +3557,7 @@ async function prepareSandboxHost(args, options = {}, overrides = {}) {
3517
3557
  await pullImage(settings.MYBASE_SANDBOX_IMAGE, io.run, false);
3518
3558
  await pullImage(settings.MYBASE_SANDBOX_WORKER_IMAGE, io.run, false);
3519
3559
  s.message("Verifying Chromium under gVisor with bounded resources");
3520
- await probeRuntime(settings.MYBASE_SANDBOX_IMAGE, io.run);
3560
+ await probeRuntime(settings.MYBASE_SANDBOX_IMAGE, io.run, config.resources);
3521
3561
  await writeFiles(dir, mergeEnv(text, settings), interactive, true);
3522
3562
  const current = { ...values, ...settings };
3523
3563
  const url = localUrl(current);
@@ -3567,6 +3607,7 @@ var WORKER_HEALTH = "fetch('http://127.0.0.1:4010/health',{headers:{Authorizatio
3567
3607
  var init_server_sandbox = __esm(async () => {
3568
3608
  init_dist4();
3569
3609
  init_public_ip();
3610
+ init_sandbox();
3570
3611
  init_src();
3571
3612
  init_output();
3572
3613
  init_server_docker();
@@ -5856,10 +5897,10 @@ await init_service_enable();
5856
5897
  var sandboxUsage = ` sandbox enable <project> [--setup-worker] [--dir <dir>] [--yes]
5857
5898
  Enable isolated compute; --setup-worker configures the local host first
5858
5899
  sandbox disable <project> [--yes] Stop sandboxes and delete their artifacts
5859
- sandbox create <project> --key <key> [--ttl 300] [--idle 120]
5900
+ sandbox create <project> --key <key> [--ttl <seconds>] [--idle <seconds>]
5860
5901
  sandbox list|get|usage <project> [<id>]
5861
5902
  sandbox terminate <project> <id> [--yes]
5862
- sandbox exec <project> <id> --key <key> [--code file.js | --command '["node","script.js"]'] [--timeout 30000]
5903
+ sandbox exec <project> <id> --key <key> [--code file.js | --command '["node","script.js"]'] [--timeout <ms>]
5863
5904
  sandbox runs|artifacts|browser <project> <id>
5864
5905
  sandbox run <project> <id> <execution>
5865
5906
  sandbox cancel <project> <id> <execution> [--yes]
@@ -5867,7 +5908,8 @@ var sandboxUsage = ` sandbox enable <project> [--setup-worker] [--dir <dir>] [-
5867
5908
  sandbox export <project> <id> <workspace-path> [--type image/png]
5868
5909
  sandbox artifact <project> <id> <artifact-id> <local-file>
5869
5910
  Creation/execution return promptly. Poll get/run. Cancelling execution terminates sandbox.
5870
- Browser credentials expire after 30s; authenticated CDP connection lasts at most 60s.`;
5911
+ No default lifetime, idle expiry, or execution timeout. Set optional deadlines as needed.
5912
+ Browser credentials expire after 30s; authenticated CDP connections have no fixed lifetime.`;
5871
5913
  async function sandbox(sub, args) {
5872
5914
  const known = ["enable", "disable", "create", "list", "get", "usage", "terminate", "exec", "runs", "run", "cancel", "upload", "download", "export", "artifacts", "artifact", "browser"];
5873
5915
  if (!known.includes(sub))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mybase-dev/cli",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "description": "The mybase CLI: projects, keys, cron, queues, cache, rate limits, analytics, docs, and agent setup for a self-hosted mybase.",
5
5
  "type": "module",
6
6
  "repository": {